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)
}
相关推荐
一生躺平的仔12 小时前
NestJS Swagger 使用说明文档
nestjs
plusone19 小时前
【Nest指北系列-源码】(七)请求生命周期
nestjs
小山不高2 天前
nest中如何对typeorm 的repo设置总的center
nestjs
bug_marker15 天前
BullMq sleep job是否会阻塞worker中的其他的jobs
nestjs
濮水大叔21 天前
快来玩玩便捷、高效的Demo练习场
typescript·nodejs·nestjs
木西21 天前
Nest.js实战:构建聊天室的群聊与私聊模块
前端·后端·nestjs
LannyChung1 个月前
NestJS定时器之@Cron
nestjs
None3211 个月前
【NestJs】集成Prisma数据库配置
nestjs
濮水大叔1 个月前
你认为Vonajs提供的这些特性会比Nestjs更好用吗?
nodejs·nestjs