我应该在哪里以及如何在passportjs中检查访问令牌的有效性

Posted

技术标签:

【中文标题】我应该在哪里以及如何在passportjs中检查访问令牌的有效性【英文标题】:Where and how should I check an access token for validity in passportjs 【发布时间】:2020-09-01 05:41:00 【问题描述】:

我正在实施刷新令牌,我使用的是 passportjs。我不完全理解的是我应该在哪里以及如何检查访问令牌的有效性,如果无效令牌到达,则抛出TokenExpiredException

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) 
    constructor(
        private readonly authService: AuthService,
    ) 
        super(
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            ignoreExpiration: false,
            secretOrKey: process.env.JWT_SECRET,
        );
    

    public async validate(payloadDto: PayloadDto): Promise<PayloadDto> 
        const validUser = await this.authService.validateUser(payloadDto);
        return  id: validUser.id, phone: validUser.phone ;
    

validateUser 方法目前如下所示:

    public async validateUser(payload: PayloadDto): Promise<UserEntity> 
        const retrievedUser: UserEntity = await this.userService.retrieveOne(payload.phone);
        if (retrievedUser) 
            return retrievedUser;
         else 
            throw new HttpException('Invalid User', HttpStatus.UNAUTHORIZED);
        
    

我想知道这样检查是否安全:

@Injectable()
export class RefreshAuthGuard extends AuthGuard('jwt') 
    public handleRequest(err: any, user: any, info: Error): any 
        if (info) 
            if (info.name === 'TokenExpiredError') 
                throw new HttpException('TokenExpired', HttpStatus.UNAUTHORIZED);
             else 
                throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED);
            
        
    

【问题讨论】:

【参考方案1】:

我建议按如下方式更改您的身份验证流程(另请参阅 thread 和 thread):

    客户端尝试使用过期的身份验证令牌调用受保护路由/secret 服务器向客户端抛出TokenExpiredError 客户端现在使用其有效的刷新令牌在身份验证服务器上请求一个新的访问令牌 身份验证服务器检查刷新令牌并向客户端发出新的访问令牌 客户端使用新的访问令牌重试/secret

刷新令牌的全部目的是它永远不会与资源服务器共享,并且不会随每个请求一起发送;这增加了安全性。如果资源服务器自己发出刷新请求,你就违背了这个目的。 如果资源服务器和身份验证服务器相同,您仍然可以从不发送如此多的长期(➡ 风险较高)令牌中受益,即通过中间人破坏它们的机会较小攻击。

【讨论】:

非常感谢!出于好奇,是否有任何替代方案可以利用该解决方案所暗示的架构来刷新令牌? 我的意思是,没有那个身份验证服务器有什么办法吗,据我所知,它必须是一个单独的微服务。 所有这些在很大程度上取决于您的要求,很难给出一个普遍的答案。身份验证服务器和资源服务器可以是同一台服务器,您仍然可以从不一直发送长期令牌中受益。但是,您可能不需要刷新令牌。您首先想要刷新令牌做什么?您是否希望能够撤销长期存在的令牌,同时在没有数据库访问(性能)的情况下保持身份验证流程?因为您也可以在没有额外刷新令牌的情况下进行会话管理。真的取决于你想做什么。 ?‍♂️

以上是关于我应该在哪里以及如何在passportjs中检查访问令牌的有效性的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Express & Passportjs 检查 MongoDB 文档中的特定字段

在 Hibernate/JPA 中,我应该在哪里以及在哪个用例中使用 SessionFactory 和 Session

在 Passportjs 中刷新 JWT 令牌

我将如何以及在哪里将这两个变量组合在 JavaScript 中?

如何将 PassportJS 与 HapiJS 一起使用

在 joomla 组件中,我应该在哪里存储数据库函数,以及如何调用它们?