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

NestJS中如何在JWT passport策略validate方法内读取access token

解决方案

你只需要在JWT策略的配置项中开启passReqToCallback参数,即可在validate方法中拿到当前请求对象,既可以提取原始待校验的access token,也能直接获取当前请求的User-Agent等信息完成设备校验,这是passport-jwt官方支持的标准用法。

修改后的可直接运行代码如下:

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { Request } from 'express';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: process.env.JWTSecret,
      // 开启配置:将请求对象透传到validate回调函数
      passReqToCallback: true,
    });
  }

  async validate(req: Request, payload: any) {
    // 提取原始access token,两种写法效果一致
    const rawAccessToken = ExtractJwt.fromAuthHeaderAsBearerToken()(req);
    // const rawAccessToken = req.headers.authorization?.replace('Bearer ', '');

    // 设备一致性校验:比对当前请求UA和token签发时存入的UA
    const currentUserAgent = req.headers['user-agent'];
    if (currentUserAgent !== payload.useragent) {
      throw new UnauthorizedException('请求设备与token签发设备不匹配');
    }

    return { userId: payload.sub, username: payload.username, useragent: payload.useragent };
  }
}
额外实现优化建议
  • 存储设备特征时不建议明文把User-Agent写入JWT payload,可以将User-Agent加盐哈希后再存入,避免payload被base64解码后直接泄露客户端特征,同时也能减少字符串比对的性能开销。
  • 如果要降低校验误杀率(比如浏览器小版本自动更新会导致UA字段变动),可以结合客户端主动上报的固定设备ID、常用IP段等特征组合校验,不要完全依赖容易变动的UA字段。
  • 生产环境建议通过NestJS内置的ConfigService读取JWTSecret等环境变量,不要直接在策略类中读取process.env,避免环境变量未完成加载时出现取值为空的异常。

内容的提问来源于stack exchange,提问作者Mohammed Tellesy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:15:37