如何在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头内容,需按以下步骤修改:
- 开启请求传递到回调:在
super的配置项中添加passReqToCallback: true,让validate方法能拿到请求对象。 - 从请求头获取完整令牌:通过
req.headers.authorization直接拿到格式为Bearer xxx的完整令牌。 - 添加黑名单校验逻辑:用拿到的令牌查询黑名单库,判断是否已被撤销。
修改后的完整代码:
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
相关产品推荐
相关产品推荐

