首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >facebook- NestJS的通行证

facebook- NestJS的通行证
EN

Stack Overflow用户
提问于 2020-05-16 09:46:46
回答 1查看 1.6K关注 0票数 8

我已经研究了passport-facebookpassport-facebook-token与NestJS的集成。问题是NestJS使用自己的实用程序(如AuthGuard )抽象了passport实现。

正因为如此,文档中记录的ExpressJS样式实现将不能与NestJS一起工作。例如,这与@nestjs/passport包不兼容:

代码语言:javascript
复制
var FacebookTokenStrategy = require('passport-facebook-token');

passport.use(new FacebookTokenStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET
  }, function(accessToken, refreshToken, profile, done) {
    User.findOrCreate({facebookId: profile.id}, function (error, user) {
      return done(error, user);
    });
  }
));

This blog post展示了一种使用不熟悉的接口实现passport-facebook-token的策略,该接口与AuthGuard不兼容。

代码语言:javascript
复制
@Injectable()
export class FacebookStrategy {
  constructor(
    private readonly userService: UserService,
  ) {
    this.init();
  }
  init() {
    use(
      new FacebookTokenStrategy(
        {
          clientID: <YOUR_APP_CLIENT_ID>,
          clientSecret: <YOUR_APP_CLIENT_SECRET>,
          fbGraphVersion: 'v3.0',
        },
        async (
          accessToken: string,
          refreshToken: string,
          profile: any,
          done: any,
        ) => {
          const user = await this.userService.findOrCreate(
            profile,
          );
          return done(null, user);
        },
      ),
    );
  }
}

这里的问题是,这似乎与NestJS期望您处理护照策略的方式完全不同。它是一起被黑的。它也可能在未来的NestJS更新中中断。这里也没有异常处理;我没有办法捕获异常,比如InternalOAuthError,由于所利用的回调性质,passport-facebook-token抛出了它。

有没有一种简洁的方法来实现passport-facebookpassport-facebook-token,这样它就可以使用@nestjs/passportvalidate()方法?从文档中可以看到:对于每种策略,Passport都会调用verify函数(通过@nestjs/passport中的validate()方法实现)。应该有一种方法在构造函数中传递clientIdclientSecret,然后将其余的逻辑放入validate()方法中。

我认为最终的结果类似于下面的内容(这不起作用):

代码语言:javascript
复制
import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import FacebookTokenStrategy from "passport-facebook-token";


@Injectable()
export class FacebookStrategy extends PassportStrategy(FacebookTokenStrategy, 'facebook')
{

    constructor()
    {
        super({
            clientID    : 'anid',     // <- Replace this with your client id
            clientSecret: 'secret', // <- Replace this with your client secret
        })
    }


    async validate(request: any, accessToken: string, refreshToken: string, profile: any, done: Function)
    {
        try
        {
            console.log(`hey we got a profile: `, profile);

            const jwt: string = 'placeholderJWT'
            const user = 
            {
                jwt
            }

            done(null, user);
        }
        catch(err)
        {
            console.log(`got an error: `, err)
            done(err, false);
        }
    }

}

在我的特殊情况下,我对callbackURL不感兴趣。我只是在验证客户端转发到服务器的访问令牌。我只是把上面的内容说得很清楚。

另外,如果您很好奇,上面的代码会生成一个InternalOAuthError,但我无法捕获策略中的异常来查看真正的问题是什么,因为它没有正确实现。我知道在这种特殊情况下,我传递的access_token是无效的,如果我传递了一个有效的one,代码就会正常工作。使用适当的实现,我将能够捕获异常,检查错误,并能够向用户冒泡出适当的异常,在本例中为HTTP401。

代码语言:javascript
复制
InternalOAuthError: Failed to fetch user profile

显然,异常是在validate()方法之外抛出的,这就是为什么我们的try/catch块没有捕获InternalOAuthError的原因。处理此异常对于正常的用户体验至关重要,我不确定在此实现中处理它的NestJS方式是什么,也不确定应该如何处理错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-16 23:53:32

通过使用extends PassportStrategy()类设置,您已经走上了正确的Strategy道路。为了捕获来自handleRequest()的错误,您可以扩展AuthGuard('facebook')并向passport添加一些自定义逻辑。您可以使用read more about it here,或者查看文档中的以下代码片段:

代码语言:javascript
复制
import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    return super.canActivate(context);
  }

  handleRequest(err, user, info) {
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}

是的,这是使用JWT而不是Facebook,但底层逻辑和处理程序是相同的,所以它应该仍然适用于您。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61830890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档