在NestJS中实现多种passport-jwt
身份验证策略通常意味着您需要定义多个策略,每个策略都有不同的验证规则或使用不同的JWT密钥。以下是一系列步骤来实现这一功能,以及一个例子:
步骤 1: 安装必要的包
首先,您需要安装Passport、passport-jwt和@nestjs/passport。
bashnpm install @nestjs/passport passport passport-jwt
步骤 2: 创建 JWT 策略
在src/auth/strategies
文件夹中创建两个文件,分别对应不同的JWT策略。
例如:
jwt.strategy.ts
(默认策略)jwt-admin.strategy.ts
(专用于管理员的策略)
每个文件将扩展PassportStrategy
类,并在构造函数中定义不同的秘密或验证选项。
步骤 3: 定义策略
在各自的策略文件中,您应该定义继承自PassportStrategy
的类,并且为每一个策略提供一个唯一的名称。
例如:
jwt.strategy.ts
:
typescriptimport { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy, ExtractJwt } from 'passport-jwt'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { constructor() { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: process.env.JWT_SECRET, }); } async validate(payload: any) { return { userId: payload.sub, username: payload.username }; } }
jwt-admin.strategy.ts
:
typescriptimport { Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy, ExtractJwt } from 'passport-jwt'; @Injectable() export class JwtAdminStrategy extends PassportStrategy(Strategy, 'jwt-admin') { constructor() { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), secretOrKey: process.env.JWT_ADMIN_SECRET, passReqToCallback: true, }); } async validate(req: Request, payload: any) { if (req.url.startsWith('/admin')) { return { adminId: payload.sub, adminName: payload.username }; } return null; } }
注意,在JwtAdminStrategy
中,我们使用了passReqToCallback: true
,它允许我们在validate
方法中访问req
对象。
步骤 4: 注册策略
在AuthModule
中,使用@Module()
装饰器注册您的策略。确保引入策略并将其添加到providers
数组中。
typescriptimport { Module } from '@nestjs/common'; import { JwtStrategy } from './strategies/jwt.strategy'; import { JwtAdminStrategy } from './strategies/jwt-admin.strategy'; @Module({ // ... providers: [JwtStrategy, JwtAdminStrategy], // ... }) export class AuthModule {}
步骤 5: 在控制器中使用策略
在您的控制器中,使用@UseGuards()
装饰器激活特定策略。
typescriptimport { Controller, Get, UseGuards } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Controller('api') export class ApiController { @Get('user') @UseGuards(AuthGuard('jwt')) getUserProfile() { // 用户端点逻辑 } @Get('admin') @UseGuards(AuthGuard('jwt-admin')) getAdminProfile() { // 管理员端点逻辑 } }
在上面的例子中,当访问/api/user
时,将使用默认的JWT策略进行身份验证,而访问/api/admin
时,将使用管理员的JWT策略进行身份验证。
注意事项
- 确保环境变量
JWT_SECRET
和JWT_ADMIN_SECRET
分别为用户JWT和管理员JWT设置了不同的密钥。 - 在
validate
方法中,您应该返回一个有效载荷对象,该对象将被附加到请求对象的user
属性。 - 如果您需要处理特定的验证逻辑,例如验证用户是否具有管理员权限,应该在
validate
方法中进行这些检查。
总之,NestJS和Passport提供了灵活的方式来定义和使用多种身份验证策略,从而使得您能够根据不同的业务场景来保护您的API。
2024年6月29日 12:07 回复