Reputation: 5628
I am implementing linkedin login strategy with passport in nestJS.
What I have right now is that I have a button "Login with linkedin" points to auth/linkedin
.
@Get('auth/linkedin')
@UseGuards(AuthGuard('linkedin'))
async linkedinAuth(@Req() req) {
}
Which works great and takes me to the linkedin login page and hits back my callback URL which is auth/linkedin/callback
with code
query string of token and this is where I am unable to figure out what todo and how to return linkedin user
@Get('auth/linkedin/callback')
@UseGuards(AuthGuard('linkedin'))
linkedinCallBack(@Req() req) {
console.log(req)
return 'handle callback!';
}
Linkedin passport strategy :
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
const LinkedInAuthStrategy = require('passport-linkedin-oauth2').Strategy;
@Injectable()
export class LinkedinStrategy extends PassportStrategy(LinkedInAuthStrategy) {
constructor(
) {
super({
clientID: 'abcd123',
clientSecret: 'abcd123',
callbackURL: 'http://localhost:5000/auth/linkedin/callback',
scope: ['r_emailaddress', 'r_liteprofile'],
}, function(accessToken, refreshToken, profile, done) {
process.nextTick(function () {
console.log(profile);
return done(null, profile);
});
})
}
}
Note: I am using this package for linkedin passport strategy
Question : How can I handle callback further with
@UseGuards
, and return LinkedIn user?
Upvotes: 2
Views: 4641
Reputation: 1174
You should adapt the LinkedinStrategy
class a bit. You can't use the done
function directly. It will be called by nest. You should have a validate
method and return a user object from it. That object will be set to the request object so in the controller you will be able to access it with req.user
. This is approximately how your class should look:
import { Strategy } from 'passport-linkedin-oauth2';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class LinkedinStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({
clientID: 'abcd123',
clientSecret: 'abcd123',
callbackURL: 'http://localhost:5000/auth/linkedin/callback',
scope: ['r_emailaddress', 'r_liteprofile'],
});
}
async validate(accessToken: string, refreshToken: string, profile: object): Promise<any> {
const user = await this.authService.validateUser(profile);
return user;
}
}
Upvotes: 3
Reputation: 25162
Check this article: OAuth2 in NestJS for Social Login (Google, Facebook, Twitter, etc) and this repo: https://github.com/thisismydesign/nestjs-starter
In the validate
method of LinkedinStrategy
you need to find or create the user (probably store in your DB), e.g.:
export class LinkedinStrategy extends PassportStrategy(Strategy) {
// constructor...
async validate(accessToken, refreshToken, profile) {
let user = await this.usersService.findOneByProvider('linkedin', profile.id);
if (!user) {
user = await this.usersService.create({
provider: 'linkedin',
providerId: id,
name: profile.name,
username: profile.email,
});
}
return user;
}
}
In the controller's callback endpoint you can issue a JWT token to handle the User's session within the app:
@Get('auth/linkedin/callback')
@UseGuards(AuthGuard('linkedin'))
linkedinCallBack(@Req() req) {
const { accessToken } = this.jwtAuthService.login(req.user);
res.cookie('jwt', accessToken);
return res.redirect('/profile');
}
Upvotes: 1