NestJS添加JWT守卫后接口返回401 无法验证x-access-token问题
问题根本原因
你的JWT守卫校验逻辑和前端传参方式不匹配,导致校验失败返回401:
- 前端将token存储在自定义请求头
x-access-token中传递 - 后端JWT策略配置的
ExtractJwt.fromAuthHeaderAsBearerToken()只会读取标准Authorization请求头中格式为Bearer <token>的内容,不会识别x-access-token字段,所以判定请求未授权。
解决方案(二选一即可)
方案1(推荐,符合JWT通用规范):修改前端请求头格式
将前端axios的请求头配置改为标准Bearer认证格式:
const response = await axios .get( '/auth/avatar', { headers: { 'Authorization': `Bearer ${sessionStorage.getItem('token')}` }, params: { username: sessionStorage.getItem('username') } } ) console.log(response.data);
方案2:修改后端JWT策略适配自定义请求头
如果不想改动前端代码,调整JWT策略的token提取规则,直接读取x-access-token头:
@Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor( @InjectRepository(UsersRepository) private usersRepository: UsersRepository, private configService: ConfigService, ) { super({ secretOrKey: configService.get('JWT_SECRET'), // 替换原有提取规则,从x-access-token头读取token jwtFromRequest: ExtractJwt.fromHeader('x-access-token'), }); } // 其余validate逻辑保持不变 }
额外校验点
如果修改后仍然报错,可依次排查以下项:
- 确认token未过期,你配置的JWT有效期为3600秒(1小时),超时后需要重新登录获取新token
- 确认JWT签发和校验阶段使用的
JWT_SECRET完全一致,没有拼写、大小写或多余空格问题 - 确认你签发JWT时的payload中确实包含
username字段,和validate方法的读取逻辑匹配
内容的提问来源于stack exchange,提问作者Andrija Gajic
相关产品推荐
相关产品推荐

