乐闻世界logo
搜索文章和话题

如何在 Nestjs 中实现多种 passport - jwt 身份验证策略

8 个月前提问
6 个月前修改
浏览次数65

1个答案

1

在NestJS中实现多种passport-jwt身份验证策略通常意味着您需要定义多个策略,每个策略都有不同的验证规则或使用不同的JWT密钥。以下是一系列步骤来实现这一功能,以及一个例子:

步骤 1: 安装必要的包

首先,您需要安装Passport、passport-jwt和@nestjs/passport。

bash
npm 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:

typescript
import { 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:

typescript
import { 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数组中。

typescript
import { 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()装饰器激活特定策略。

typescript
import { 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_SECRETJWT_ADMIN_SECRET分别为用户JWT和管理员JWT设置了不同的密钥。
  • validate方法中,您应该返回一个有效载荷对象,该对象将被附加到请求对象的user属性。
  • 如果您需要处理特定的验证逻辑,例如验证用户是否具有管理员权限,应该在validate方法中进行这些检查。

总之,NestJS和Passport提供了灵活的方式来定义和使用多种身份验证策略,从而使得您能够根据不同的业务场景来保护您的API。

2024年6月29日 12:07 回复

你的答案