Javascript NestJS:Auth-guard流

Javascript NestJS:Auth-guard流,javascript,node.js,passport.js,linkedin,nestjs,Javascript,Node.js,Passport.js,Linkedin,Nestjs,我正在用nestJS中的passport实现linkedin登录策略。 我现在拥有的是一个按钮“使用linkedin登录”指向auth/linkedin @Get('auth/linkedin') @UseGuards(AuthGuard('linkedin')) async linkedinAuth(@Req() req) { } 这非常有效,将我带到linkedin登录页面,用codetoken的查询字符串回击我的回调URL,即auth/linkedin/callback,这就是

我正在用nestJS中的passport实现linkedin登录策略。 我现在拥有的是一个按钮“使用linkedin登录”指向
auth/linkedin

@Get('auth/linkedin')
@UseGuards(AuthGuard('linkedin'))
async linkedinAuth(@Req() req) {
    
}
这非常有效,将我带到linkedin登录页面,用
code
token的查询字符串回击我的回调URL,即
auth/linkedin/callback
,这就是我无法确定要做什么以及如何返回linkedin用户的地方

@Get('auth/linkedin/callback')
@UseGuards(AuthGuard('linkedin'))
linkedinCallBack(@Req() req) {
  console.log(req)
  return 'handle callback!';
}
Linkedin护照策略:

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);
      });
    })
  }
}
注意:我将此用于linkedin passport策略

问题:如何使用
@UseGuards
进一步处理回调,并返回LinkedIn用户?


您应该稍微调整一下
LinkedIn策略
类。您不能直接使用
done
功能。它将被nest调用。您应该有一个
validate
方法,并从中返回一个用户对象。该对象将被设置为请求对象,因此在控制器中,您可以使用
req.user
访问该对象。这大致是您的类的外观:

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;
  }
}
从“passport-linkedin-oauth2”导入{Strategy};
从'@nestjs/passport'导入{PassportStrategy};
从'@nestjs/common'导入{可注射的,未授权的dexception};
从“/auth.service”导入{AuthService};
@可注射()
导出类LinkedIn策略扩展PassportStrategy(策略){
构造函数(专用authService:authService){
超级({
客户ID:“abcd123”,
客户机密:“abcd123”,
callbackURL:'http://localhost:5000/auth/linkedin/callback',
范围:['r_电子邮件地址','r_liteprofile'],
});
}
异步验证(accessToken:string,refreshToken:string,profile:object):承诺{
const user=wait this.authService.validateUser(配置文件);
返回用户;
}
}

您应该稍微调整
链接策略
类。您不能直接使用
done
功能。它将被nest调用。您应该有一个
validate
方法,并从中返回一个用户对象。该对象将被设置为请求对象,因此在控制器中,您可以使用
req.user
访问该对象。这大致是您的类的外观:

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;
  }
}
从“passport-linkedin-oauth2”导入{Strategy};
从'@nestjs/passport'导入{PassportStrategy};
从'@nestjs/common'导入{可注射的,未授权的dexception};
从“/auth.service”导入{AuthService};
@可注射()
导出类LinkedIn策略扩展PassportStrategy(策略){
构造函数(专用authService:authService){
超级({
客户ID:“abcd123”,
客户机密:“abcd123”,
callbackURL:'http://localhost:5000/auth/linkedin/callback',
范围:['r_电子邮件地址','r_liteprofile'],
});
}
异步验证(accessToken:string,refreshToken:string,profile:object):承诺{
const user=wait this.authService.validateUser(配置文件);
返回用户;
}
}
查看本文:以及本回购协议:

LinkedIn策略的
validate
方法中,您需要查找或创建用户(可能存储在数据库中),例如:

导出类LinkedIn策略扩展了PassportStrategy(策略){
//构造器。。。
异步验证(accessToken、refreshToken、概要文件){
让user=wait this.usersService.findOneByProvider('linkedin',profile.id);
如果(!用户){
user=等待this.usersService.create({
提供者:“linkedin”,
providerId:id,
名称:profile.name,
用户名:profile.email,
});
}
返回用户;
}
}
在控制器的回调端点中,您可以发出JWT令牌来处理应用程序中的用户会话:

@Get('auth/linkedin/callback'))
@UseGuard(AuthGuard('linkedin'))
linkedinCallBack(@Req()Req){
const{accessToken}=this.jwtAuthService.login(req.user);
res.cookie('jwt',accessToken);
返回res.redirect('/profile');
}
查看本文:以及本回购协议:

LinkedIn策略的
validate
方法中,您需要查找或创建用户(可能存储在数据库中),例如:

导出类LinkedIn策略扩展了PassportStrategy(策略){
//构造器。。。
异步验证(accessToken、refreshToken、概要文件){
让user=wait this.usersService.findOneByProvider('linkedin',profile.id);
如果(!用户){
user=等待this.usersService.create({
提供者:“linkedin”,
providerId:id,
名称:profile.name,
用户名:profile.email,
});
}
返回用户;
}
}
在控制器的回调端点中,您可以发出JWT令牌来处理应用程序中的用户会话:

@Get('auth/linkedin/callback'))
@UseGuard(AuthGuard('linkedin'))
linkedinCallBack(@Req()Req){
const{accessToken}=this.jwtAuthService.login(req.user);
res.cookie('jwt',accessToken);
返回res.redirect('/profile');
}

是有道理的,但是如何处理回调URL
auth/linkedin/callback
validate
方法的逻辑将仅在回调情况下运行。在第一种情况下,nest将在调用
validate
之前重定向到linkedin页面。因此,您可以在validate方法或控制器中处理回调。同样,无论您从validate方法返回什么,都可以从
req.user
访问。我有不同的登录页面…重定向到linkedin页面时,是否有一种方法标记一些自定义参数,以便在回调后可以保留和使用?这很有意义,但是如何处理回调URL
auth/linkedin/callback
validate
方法的逻辑将仅在回调情况下运行。在第一种情况下,nest将在调用
validate
之前重定向到linkedin页面。因此,您可以在validate方法或控制器中处理回调。再说一遍,wh