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)
}
相关推荐
亮子AI18 天前
【NestJS】为什么return不返回客户端?
前端·javascript·git·nestjs
小p19 天前
nestjs学习2:利用typescript改写express服务
nestjs
Eric_见嘉24 天前
NestJS 🧑‍🍳 厨子必修课(九):API 文档 Swagger
前端·后端·nestjs
XiaoYu20021 个月前
第3章 Nest.js拦截器
前端·ai编程·nestjs
XiaoYu20021 个月前
第2章 Nest.js入门
前端·ai编程·nestjs
实习生小黄1 个月前
NestJS 调试方案
后端·nestjs
当时只道寻常1 个月前
NestJS 如何配置环境变量
nestjs
濮水大叔2 个月前
VonaJS是如何做到文件级别精确HMR(热更新)的?
typescript·node.js·nestjs
ovensi2 个月前
告别笨重的 ELK,拥抱轻量级 PLG:NestJS 日志监控实战指南
nestjs