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

Typescript 我应该在哪里以及如何在passportjs中检查访问令牌的有效性,typescript,nestjs,Typescript,Nestjs,我正在实现刷新令牌,我使用passportjs。我不完全理解的是,我应该在哪里以及如何检查访问令牌的有效性,如果无效令牌到达,则抛出TokenExpiredException @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor( private readonly authService: AuthService, ) { su

我正在实现刷新令牌,我使用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 };
    }
}
我想知道这样检查是否安全:

    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);
            }
        }
    }
}

我建议如下更改您的身份验证流程(另请参见和):

  • 客户端尝试使用过期的身份验证令牌调用受保护路由
    /secret
  • 服务器向客户端抛出
    TokenExpiredError
  • 客户端现在使用其有效的刷新令牌在身份验证服务器上请求一个新的访问令牌
  • 身份验证服务器检查刷新令牌并向客户端发出新的访问令牌
  • 客户端使用其新的访问令牌重试
    /secret
  • 刷新令牌的全部用途是它永远不会与资源服务器共享,也不会随每个请求一起发送;这增加了安全性。如果资源服务器本身发出刷新请求,则无法达到此目的。
    如果资源服务器和身份验证服务器相同,您仍然可以从不发送长期有效的(➡ 更高的风险)代币数量如此之多,也就是说,通过中间人的攻击,它们被破坏的可能性更小。

    非常感谢!出于好奇,有没有其他方法可以利用此解决方案所暗示的体系结构来刷新令牌?我的意思是,没有身份验证服务器,有没有其他方法可以做到?据我所知,这必须是一个单独的微服务。所有这些都强烈地取决于您的需求,很难给出一个一般性的答案。身份验证服务器和资源服务器可以是同一台服务器,但您仍然可以从不始终发送长寿命令牌中获益。但是,您可能不需要刷新令牌。首先,你想要刷新令牌做什么?您是否希望能够在不使用db访问(性能)的情况下维护身份验证流的同时撤销长期令牌?因为您还可以在不使用其他刷新令牌的情况下进行会话管理。这取决于你想做什么。