Nestjs集成JWT实现无状态身份验证教程
在使用NestJS集成JWT进行无状态身份验证时遇到了几个问题:
- 如何正确配置JWT模块?官方文档的示例不太清晰
- 前端请求时Authorization头应该如何设置格式?Bearer token的具体实现方式是什么
- 为什么我的Token验证中间件总是返回401错误?已经检查过密钥是正确的
- 如何实现Token自动刷新机制?现有的access_token过期后该如何处理
- 在生产环境中应该如何安全地存储JWT_SECRET?目前是直接写在环境变量里
3 回复
- 安装依赖:
npm install @nestjs/jwt @nestjs/passport passport passport-local bcryptjs
- 配置JWT模块,在 AppModule 中引入 JwtModule 并设置密钥。
- 创建 AuthModule,导入 PassportModule 和 JwtStrategy。
- 实现 JwtStrategy,使用
@Injectable()
装饰器,并注入 JwtService 和 ConfigService。 - 编写登录接口,验证用户信息后生成 JWT Token。
- 在需要认证的路由上使用
@UseGuards(JwtAuthGuard)
。 - 前端请求时携带 Authorization 头部,值为 Bearer <token>。
示例代码:
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private config: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: config.get('JWT_SECRET'),
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
这种方式使服务间通信无需保存用户状态,适合微服务架构。
要在NestJS中集成JWT实现无状态身份验证,可按以下步骤操作:
-
安装依赖:
npm install [@nestjs](/user/nestjs)/jwt [@nestjs](/user/nestjs)/passport passport passport-jwt jsonwebtoken
-
配置Passport和JWT模块: 在
app.module.ts
中引入JwtModule
并配置秘钥:import { Module } from '[@nestjs](/user/nestjs)/common'; import { JwtModule } from '[@nestjs](/user/nestjs)/jwt'; [@Module](/user/Module)({ imports: [ JwtModule.register({ secret: 'your-secret-key', // 替换为自己的密钥 signOptions: { expiresIn: '60s' }, }), ], }) export class AppModule {}
-
创建Auth策略: 创建
auth.strategy.ts
文件:import { ExtractJwt, Strategy } from 'passport-jwt'; import { PassportStrategy } from '[@nestjs](/user/nestjs)/passport'; import { Injectable } from '[@nestjs](/user/nestjs)/common'; [@Injectable](/user/Injectable)() export class JwtStrategy extends PassportStrategy(Strategy) { constructor() { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, secretOrKey: 'your-secret-key', }); } async validate(payload: any) { return { userId: payload.sub, username: payload.username }; } }
-
生成JWT令牌: 在登录接口中生成JWT:
import { Injectable } from '[@nestjs](/user/nestjs)/common'; import { JwtService } from '[@nestjs](/user/nestjs)/jwt'; [@Injectable](/user/Injectable)() export class AuthService { constructor(private jwtService: JwtService) {} async login(user: any) { const payload = { username: user.username, sub: user.userId }; return { access_token: this.jwtService.sign(payload), }; } }
-
保护路由: 使用
@UseGuards
装饰器添加JWT认证:import { Controller, UseGuards, Request, Post, Body } from '[@nestjs](/user/nestjs)/common'; import { AuthGuard } from '[@nestjs](/user/nestjs)/passport'; [@Controller](/user/Controller)('auth') export class AuthController { @UseGuards(AuthGuard('jwt')) @Post('profile') getProfile(@Request() req) { return req.user; } }
完成以上步骤后,你就成功集成了JWT到NestJS项目中,可以实现无状态的身份验证了。
NestJS集成JWT实现无状态身份验证教程
1. 安装必要依赖
npm install @nestjs/jwt passport passport-jwt
npm install @types/passport-jwt --save-dev
2. 配置JWT模块
// auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
@Module({
imports: [
JwtModule.register({
secret: 'your_secret_key', // 替换为你的密钥
signOptions: { expiresIn: '60s' }, // 令牌有效期
}),
],
providers: [AuthService],
exports: [AuthService],
})
export class AuthModule {}
3. 创建认证服务
// auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(private readonly jwtService: JwtService) {}
async generateToken(user: any) {
const payload = { username: user.username, sub: user.userId };
return {
access_token: this.jwtService.sign(payload),
};
}
}
4. 配置Passport策略
// jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: 'your_secret_key', // 与JWT模块中的密钥一致
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
5. 创建保护路由的守卫
// auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
6. 使用示例
// auth.controller.ts
import { Controller, Post, Request, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalAuthGuard } from './local-auth.guard';
@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}
@Post('login')
async login(@Request() req) {
return this.authService.generateToken(req.user);
}
@UseGuards(JwtAuthGuard)
@Get('profile')
getProfile(@Request() req) {
return req.user;
}
}
7. 配置全局守卫(可选)
// main.ts
app.useGlobalGuards(new JwtAuthGuard());
这样你就完成了NestJS中JWT无状态身份验证的集成。客户端需要在请求头中添加Authorization: Bearer <token>
来访问受保护的路由。