NestJS v5.0.0如何配置Passport实现全局所有路由鉴权?
升级NestJS v5实现全局路由鉴权
嘿,我来帮你搞定NestJS v5的全局鉴权配置!从你的旧代码来看,你之前是通过中间件全局应用JWT鉴权,在v5版本里,我们有两种方式可以实现相同的效果,其中更推荐的是使用全局守卫(符合NestJS的最佳实践),当然也可以沿用类似旧代码的中间件写法,下面分别给你说明:
方式一:使用全局守卫(推荐)
NestJS v5之后,框架更推荐用「守卫」来处理鉴权逻辑,它能更好地集成框架的上下文、异常处理等能力,实现全局鉴权的步骤如下:
创建JWT鉴权守卫
先写一个继承自AuthGuard('jwt')的守卫类:import { Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') {}在AuthModule中注册全局守卫
修改你的AuthModule,把刚才的守卫注册为全局守卫,这样它会自动作用于所有路由:import { Module, APP_GUARD } from '@nestjs/common'; import { AuthService } from './auth.service'; import { JwtStrategy } from './jwt.strategy'; import { Config } from './config'; import { AuthenticateController } from './authenticate.controller'; import { JwtAuthGuard } from './jwt-auth.guard'; @Module({ components: [AuthService, JwtStrategy, Config], controllers: [AuthenticateController], providers: [ { provide: APP_GUARD, useClass: JwtAuthGuard, }, ], }) export class AuthModule {}(可选)跳过指定路由的鉴权
如果像登录这类路由不需要鉴权,可以自定义一个装饰器来标记:import { SetMetadata } from '@nestjs/common'; export const Public = () => SetMetadata('isPublic', true);然后修改守卫,加入跳过逻辑:
import { Injectable, ExecutionContext } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { Reflector } from '@nestjs/core'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { constructor(private reflector: Reflector) { super(); } canActivate(context: ExecutionContext) { // 检查当前路由是否标记为公开 const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [ context.getHandler(), context.getClass(), ]); if (isPublic) { return true; } // 否则执行正常的JWT鉴权 return super.canActivate(context); } }最后在不需要鉴权的路由上加上
@Public()装饰器即可:@Public() @Post('login') async login(@Body() loginDto: LoginDto) { // 你的登录逻辑 }
方式二:沿用中间件写法(和旧代码逻辑一致)
如果你更习惯用中间件的方式,v5版本依然支持这种写法,代码和旧版本几乎一样,只要确保依赖导入正确即可:
import { Module, NestModule, MiddlewaresConsumer, RequestMethod } from '@nestjs/common'; import { AuthService } from './auth.service'; import { JwtStrategy } from './jwt.strategy'; import { Config } from './config'; import { AuthenticateController } from './authenticate.controller'; import * as passport from 'passport'; @Module({ components: [AuthService, JwtStrategy, Config], controllers: [AuthenticateController], }) export class AuthModule implements NestModule { configure(consumer: MiddlewaresConsumer) { consumer .apply(passport.authenticate('jwt', { session: false })) .forRoutes({ path: '*', method: RequestMethod.ALL }); } }
需要注意的是,这种方式要确保你已经正确配置了Passport和JwtStrategy,否则中间件无法正常工作。不过还是更推荐第一种守卫的方式,扩展性更强哦!
内容的提问来源于stack exchange,提问作者Mss Menme
相关产品推荐
相关产品推荐

