You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Passport回调解码前的validate方法中获取Access Token?

获取JwtStrategy validate方法中的完整Bearer令牌

问题说明

需要在JwtStrategy的validate方法中获取格式为Bearer e*****.....的完整Access Token,用于校验令牌是否被数据库中的黑名单记录撤销。现有代码无法直接获取该令牌:

export class JwtStrategy extends PassportStrategy(Strategy) {
    
    constructor(private readonly accountService: AccountService,
        @InjectRepository(BlacklistRepository) private blacklistRepository: BlacklistRepository,
        private readonly customerService: CustomerService,
    ) {
        super({
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            // ignoreExpiration: true,
            secretOrKey: config['jhipster.security.authentication.jwt.base64-secret'],
        });
    }

    async validate(payload: Payload, done: VerifiedCallback): Promise<any> {
        
        console.log(accessToken) // 需要获取格式为 'Bearer e*****.....' 的令牌
     
        if (!user) {
            return done(new UnauthorizedException({ message: 'user does not exist' }), false);
        }
        return done(null, user);
    }
}

解决方案

默认的ExtractJwt.fromAuthHeaderAsBearerToken()只会提取令牌的核心部分(不带Bearer 前缀),要获取完整的Authorization头内容,需按以下步骤修改:

  1. 开启请求传递到回调:在super的配置项中添加passReqToCallback: true,让validate方法能拿到请求对象。
  2. 从请求头获取完整令牌:通过req.headers.authorization直接拿到格式为Bearer xxx的完整令牌。
  3. 添加黑名单校验逻辑:用拿到的令牌查询黑名单库,判断是否已被撤销。

修改后的完整代码:

import { Request } from 'express'; // 或从@nestjs/common导入,根据项目框架调整

export class JwtStrategy extends PassportStrategy(Strategy) {
    
    constructor(private readonly accountService: AccountService,
        @InjectRepository(BlacklistRepository) private blacklistRepository: BlacklistRepository,
        private readonly customerService: CustomerService,
    ) {
        super({
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            // ignoreExpiration: true,
            secretOrKey: config['jhipster.security.authentication.jwt.base64-secret'],
            passReqToCallback: true // 新增:将请求对象传递到validate方法
        });
    }

    // 修改参数:第一个参数为请求对象req
    async validate(req: Request, payload: Payload, done: VerifiedCallback): Promise<any> {
        // 获取完整的Bearer令牌
        const accessToken = req.headers.authorization;
        
        if (!accessToken) {
            return done(new UnauthorizedException({ message: 'Authorization header missing' }), false);
        }

        // 校验令牌是否在黑名单中
        const isBlacklisted = await this.blacklistRepository.findOne({ where: { token: accessToken } });
        if (isBlacklisted) {
            return done(new UnauthorizedException({ message: 'Token has been revoked' }), false);
        }

        // 原有的用户校验逻辑
        const user = await this.accountService.findUserById(payload.sub);
        if (!user) {
            return done(new UnauthorizedException({ message: 'user does not exist' }), false);
        }
        return done(null, user);
    }
}

注意事项

  • 确保Request对象已根据项目框架正确导入(Express或NestJS等)。
  • 可额外添加格式校验,确保accessToken符合Bearer xxx的格式,避免后续逻辑报错。

内容的提问来源于stack exchange,提问作者Adebowale Mujeeb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:51:37