使用NestJS中间件时能否传递参数?CookieMiddleware实践疑问
在NestJS中给带构造函数参数的中间件传参的正确方式
你直接用mixin CookieMiddleware("some string param")这种方式是行不通的,因为Nest的mixin工具是用来动态生成类的,直接传参无法正确处理依赖注入逻辑。下面给你两种可行的解决方案:
方案一:用工厂函数动态生成中间件类
这种方式适合不同路由需要不同Role参数的场景,通过工厂函数返回绑定了特定参数的中间件类:
import { Injectable, NestMiddleware } from '@nestjs/common'; import { ExtendedRequest, IUserCookie, Role } from './your-types'; import { Response, NextFunction } from 'express'; import * as _ from 'lodash'; import { AuthorizationError } from './your-errors'; import { AuthService } from './auth.service'; export function createCookieMiddleware(role: Role) { @Injectable() class CookieMiddlewareWithRole implements NestMiddleware { private readonly role: Role; constructor() { this.role = role; } private isEmpty(user: IUserCookie) { return _.some(user, (val) => !!val); } use(req: ExtendedRequest, res: Response, next: NextFunction) { const token = req.cookies[this.role + 'Authorization']; const refreshToken = req.cookies[this.role + 'Refresh']; if (!token && !refreshToken) throw new AuthorizationError(); const refreshData = AuthService.deTokenizData<IUserCookie>(refreshToken); let userData = AuthService.deTokenizData<IUserCookie>(token); if (!refreshData && !userData) throw new AuthorizationError(); if (!userData || !refreshData) { const tokenType = !userData ? 'Authorization' : 'Refresh'; const data = !userData ? AuthService.deTokenizData<IUserCookie>(refreshToken) : userData; if (!data) throw new AuthorizationError(); res.cookie(this.role + tokenType, data); userData = data; } if (this.isEmpty(userData)) throw new AuthorizationError(); req.user = userData; next(); } } return CookieMiddlewareWithRole; }
在模块中使用时,直接调用工厂函数并传入参数:
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; import { createCookieMiddleware } from './cookie.middleware'; @Module({ // 模块其他配置 }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(createCookieMiddleware('admin')) // 传递admin角色 .forRoutes('admin/**'); consumer .apply(createCookieMiddleware('user')) // 传递user角色 .forRoutes('user/**'); } }
方案二:通过依赖注入自定义参数
如果你的中间件在整个模块中只需要使用同一个Role参数,可以通过自定义提供者来注入:
首先修改中间件的构造函数,使用@Inject装饰器指定注入的token:
import { Injectable, Inject, NestMiddleware } from '@nestjs/common'; // 其他导入... @Injectable() export default class CookieMiddleware implements NestMiddleware { constructor(@Inject('ROLE') private role: Role) {} // 原有方法不变... }
然后在模块中注册中间件时,提供对应的参数值:
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; import CookieMiddleware from './cookie.middleware'; @Module({ providers: [ { provide: 'ROLE', useValue: 'admin' // 这里设置要传递的Role值 }, CookieMiddleware ] }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(CookieMiddleware) .forRoutes('admin/**'); } }
这样Nest会在实例化中间件时,把'admin'注入到构造函数的role参数中。
内容的提问来源于stack exchange,提问作者xKralTr
相关产品推荐
相关产品推荐

