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)
}
相关推荐
kongxx9 天前
NestJS中使用Guard实现路由保护
nestjs
白雾茫茫丶10 天前
Nest.js 实战 (十二):优雅地使用事件发布/订阅模块 Event Emitter
nestjs·nest.js·发布订阅·event emitter
lph65821 个月前
比起上传资源更应该懂得如何资源回收
node.js·nestjs
gsls2008081 个月前
将nestjs项目迁移到阿里云函数
阿里云·云计算·nestjs·云函数
d3126975101 个月前
在Nestjs使用mysql和typeorm
mysql·express·nestjs·typeorm
剪刀石头布啊2 个月前
nestjs-版本控制
nestjs
潇洒哥gg2 个月前
重生之我在NestJS中使用jwt鉴权
前端·javascript·nestjs
huangkaihao2 个月前
【NestJS学习笔记】 之 自定义装饰器
前端·node.js·nestjs
鹿鹿鹿鹿isNotDefined2 个月前
Nest 源码解析:依赖注入是怎么实现的?
nestjs