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

如何在NestJS中验证Laravel Passport签发的Bearer Token?

Laravel Passport Token 在 NestJS 微服务中的本地验证方案

方案可行性

完全可行。Laravel Passport 默认签发的是 RS256 算法签名的 JWT 格式 Bearer Token,只要拿到对应的公钥,就能在 NestJS 中直接本地验证,无需每次请求 Laravel API 做校验。


具体实现步骤

1. 从 Laravel 项目获取验证所需资源

  • 公钥:在 Laravel 项目中,执行 php artisan passport:keys 生成的公钥文件位于 storage/oauth-public.key,将该文件复制到 NestJS 项目的配置目录(比如 config/),或者复制文件内容用于后续配置。
  • Issuer 地址:Laravel 项目 .env 中的 APP_URL(Token payload 中的 iss 字段值)。

2. 安装 NestJS 依赖包

执行以下命令安装 JWT 验证相关依赖:

npm install @nestjs/jwt @nestjs/passport passport-jwt
npm install -D @types/passport-jwt

3. 实现 JWT 验证策略

创建 src/auth/jwt.strategy.ts 文件,编写验证逻辑:

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import * as fs from 'fs';
import * as path from 'path';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      // 从请求头的 Authorization 中提取 Bearer Token
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      // 不忽略过期时间,过期 Token 直接拒绝
      ignoreExpiration: false,
      // 加载 Laravel 公钥用于验证签名
      secretOrKey: fs.readFileSync(path.join(__dirname, '../../config/oauth-public.key'), 'utf8'),
      // 指定 Token 的 issuer(需与 Laravel 的 APP_URL 一致)
      issuer: 'http://localhost:8000',
      // Laravel Passport 默认用 RS256 算法,必须指定
      algorithms: ['RS256'],
    });
  }

  // Token 验证通过后,解析 payload 并返回用户信息供接口使用
  async validate(payload: any) {
    // 可根据业务需求从数据库查询用户详情,或直接返回 payload 中的字段
    return { userId: payload.sub, email: payload.email };
  }
}

4. 注册 Auth 模块

创建 src/auth/auth.module.ts,将策略和 JWT 模块注册到 NestJS:

import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { JwtStrategy } from './jwt.strategy';
import * as fs from 'fs';
import * as path from 'path';

@Module({
  imports: [
    PassportModule,
    JwtModule.register({
      secret: fs.readFileSync(path.join(__dirname, '../../config/oauth-public.key'), 'utf8'),
      signOptions: { issuer: 'http://localhost:8000', algorithm: 'RS256' },
    }),
  ],
  providers: [JwtStrategy],
  exports: [JwtModule],
})
export class AuthModule {}

5. 保护接口

在需要验证的控制器中,使用 @UseGuards(AuthGuard('jwt')) 装饰器保护接口:

import { Controller, Get, UseGuards, Request } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller('user')
export class UserController {
  @Get('profile')
  @UseGuards(AuthGuard('jwt'))
  getProfile(@Request() req) {
    return {
      message: '获取用户信息成功',
      user: req.user
    };
  }
}

常见验证失败排查点

  • 算法不匹配:必须指定 algorithms: ['RS256'],Laravel Passport 不使用 HS256 算法,用错会直接验证失败。
  • 公钥错误:确保使用的是 oauth-public.key 而不是私钥 oauth-private.key,公钥内容必须完整(包含-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----)。
  • Issuer 不匹配:NestJS 配置的 issuer 必须和 Laravel 的 APP_URL 完全一致,包括协议(http/https)和端口。
  • Token 格式问题:请求头必须是 Authorization: Bearer <token>,注意 Bearer 后有一个空格,Token 不能有多余的换行或空格。
  • 公钥加载失败:如果用环境变量存储公钥,注意处理换行符转义问题,建议直接用文件读取方式加载公钥更可靠。

内容的提问来源于stack exchange,提问作者LY-92

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:40:06