nestjs-自定义装饰器

前面讲过通过 SetMetadata 装饰器 包装我们自己的装饰器,让其帮我们保存数据,然后再 guard中通过 context、reflector 获取该参数协助我们验权,也讲了通过 headers 装饰器包装我们的装饰器,终归限制很大,这里直接使用补充一个 createParamDecorator 创建我们自己的参数装饰器

先回顾一下我们使用 SetMetadata 封装的权限相关装饰器,

js 复制代码
//使用 SetMetadata 包装我们自己的装饰器
export const PUBLIC_KEY = '__public_key';
export const Public = () => SetMetadata(PUBLIC_KEY, PublicStatus.default);
//默认带token的,有user返回user
export const PublicUser = () => SetMetadata(PUBLIC_KEY, PublicStatus.token);


//在后续校验使用时,通过装饰器相关参数,获取到我们保存的数据
const publicStatus = this.reflector.getAllAndOverride<PublicStatus>(
  PUBLIC_KEY,
  [context.getHandler(), context.getClass()],
);

在回顾一下 Headers 装饰器包装的我们自己的装饰器,前面也说过,映射参数dto文档时,会把header里面加入的东西也映射出来,很不方便

js 复制代码
//设置一个key,方便快速通过装饰器获取用户信息,在jwt验证时存入,这里获取(由于header会映射出参数,使用request)
export const USER_ID_KEY  = '__user_id_key';
export const ReqUserId = () => Headers(USER_ID_KEY);

//如果保存的是 user 则可以用这个(由于header会映射出参数,使用request)
export const USER_KEY  = '__user_key';
export const ReqUser = () => Headers(USER_KEY);

//guard文件
canActivate(
    context: ExecutionContext,
  ): boolean {
    const request = context.switchToHttp().getRequest();
    let headers = request.headers
    const id=..., user=...
    //给我们的 headers 赋值,装饰器获取参数时,通过 Headers装饰器 取出
    headers[USER_ID_KEY] = id;
    headers[USER_KEY] = user;
  }
}

上面的Header装饰器包装的装饰器不太符合我们的要求,我们就通过 createParamDecorator包装一个适合我们的 User 装饰器 吧,其也不会被映射出来了

js 复制代码
//这里可以获取传递的参数,还有context
export const User = createParamDecorator(
    (data: string | undefined | null, ctx: ExecutionContext) => {
    //获取 request 
    const request = ctx.switchToHttp().getRequest();
    //鉴权时,如果登陆就保存一下user
    const user = request.user
    //外部装饰器传递参数,直接
    return data ? user?.[data] : user    
});
//我们的user的id就是id,直接传递id即可
export const ReqUserId = () => User('id');
//这里是为了兼容老写法,多加了一个,可以直接使用 @User
export const ReqUser = (key?: string | null) => User(key);

canActivate(
    context: ExecutionContext,
  ): boolean {
    const publicStatus = this.reflector.getAllAndOverride<PublicStatus>(
      PUBLIC_KEY,
      [context.getHandler(), context.getClass()],
    );
    
    const request = context.switchToHttp().getRequest();
    request[USER_KEY] = user;
  }
}

封装完毕,我们使用一下,记得别导入错了 User 类哈(有一个 UserEntity类)

js 复制代码
@ApiOperation({
    summary: '我的专栏',
})
@Post('features')
features(@User() user: User) {
    console.log(user)
}
相关推荐
全栈王校长3 天前
Nest IoC 依赖注入 - 一次彻底讲明白
nestjs
全栈王校长3 天前
前端转后端?用 Vue 的思维学 NestJS,真香!
nestjs
当时只道寻常3 天前
NestJS Redis 原子限流守卫 防刷防攻击
后端·nestjs
踩着两条虫3 天前
VTJ.PRO 在线应用开发平台的Open API 与外部集成
低代码·ai编程·nestjs
www_stdio4 天前
🚀 从 Event Loop 到 AI Agent:我的 Node.js 全栈进阶之路
前端·node.js·nestjs
Bigger4 天前
🚀 开源发布!从 0 到 1,使用 Next.js + Nest.js 构建全栈自动化数据分析 AI Agent
agent·nestjs·next.js
踩着两条虫6 天前
VTJ.PRO 在线应用开发平台的数据库与基础设施
数据库·架构·nestjs
踩着两条虫7 天前
VTJ.PRO 在线应用开发平台的后端模块系统
后端·架构·nestjs
踩着两条虫7 天前
VTJ.PRO 在线应用开发平台的业务模块(应用、DSL、模板、订单、智能体、技能)
后端·agent·nestjs
踩着两条虫7 天前
VTJ.PRO 在线应用开发平台的核心模块(用户、认证、RBAC、缓存、设置)
后端·低代码·nestjs