首页 > 解决方案 > 我应该在哪里以及如何在passportjs中检查访问令牌的有效性

问题描述

我正在实施刷新令牌,我使用的是 passportjs。我不完全理解的是我应该在哪里以及如何检查访问令牌的有效性,以及如果无效令牌到达 throw 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);
            }
        }
    }
}

标签: typescriptnestjs

解决方案


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

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

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


推荐阅读