Nest.js框架(4)

守卫

卫是一个使用 @Injectable() 装饰器的类。 守卫应该实现 CanActivate 接口。
 
守卫有一个单独的责任。它们根据运行时出现的某些条件(例如权限,角色,访问控制列表等)来确定给定的请求是否由路由处理程序处理。 这通常称为
授权。在传统的 Express 应用程序中,通常由中间件处理授权。中间件是身份验证的良好选择。到目前为止,访问限制逻辑大多在中间件内。这样很好,因
为诸如 token 验证或将 request 对象附加属性与特定路由没有强关联。
 
中间件不知道调用 next() 函数后会执行哪个处理程序。另一方面,警卫可以访问 ExecutionContext 实例,因此确切地知道接下来要执行什么。它们的设计与
异常过滤器、管道和拦截器非常相似,目的是让您在请求 / 响应周期的正确位置插入处理逻辑,并以声明的方式进行插入。这有助于保持代码的简洁和声明
性。
 
守卫在每个中间件之后执行,但在任何拦截器或管道之前执行。
 

授权守卫-AuthGuard

授权是守卫的一个很好的示例,因为只有当调用者 ( 通常是经过身份验证的特定用户 ) 具有足够的权限时,特定的路由才可用。我们现
在要构建的 AuthGuard 假设用户是经过身份验证的 ( 因此,请求头附加了一个 token) 。它将提取和验证 token ,并使用提取的信息来确定
请求是否可以继续。
 

认识token

 
HTTP 协议,是一种无状态的协议
  比如:用户登陆成功,服务器没办法记录你登陆成功的状态
 
什么是 token
 
token 可以翻译为令牌;
 
也就是在验证了用户账号和密码正确的情况,给用户颁发一个令牌;
 
这个令牌作为后续用户访问一些接口或者资源的凭证;
 
我们可以根据这个凭证来判断用户是否有权限来访问;
 
所以 token 的使用应该分成两个重要的步骤:
 
生成 token :登录的时候,颁发 token
 
验证 token :访问某些资源或者接口时,验证 token
 

JWT实现Token机制

JWT 生成的 Token 由三部分组成:
 
header
 
alg :采用的加密算法,默认是 HMAC
SHA256 HS256 ),采用同一个密钥进行
加密和解密;
 
typ JWT ,固定值,通常都写成 JWT 即可;
 
会通过 base64Url 算法进行编码;
 
payload
 
携带的数据,比如我们可以将用户的 id name 放到 payload 中;
 
默认也会携带 iat issued at ),令牌的签发时间;
 
我们也可以设置过期时间: exp expiration time );
 
会通过 base64Url 算法进行编码
 
signature
 
设置一个 secretKey ,通过将前两个的结果合并后进行 HMACSHA256 的算法;
 
HMACSHA256(base64Url(header)+.+base64Url(payload), secretKey);
 
但是如果 secretKey 暴露是一件非常危险的事情,因为之后就可以模拟颁发 token
也可以解密 token
 

Nest中使用JWT颁发令牌和验证令牌

绑定守卫

与管道和异常过滤器一样,守卫可以是控制器范围的、方法范围的或全局范围的。
 
@UseGuards() 装饰器设置了一个控制范围的守卫。这个装饰器可以使用单个参数,也可以使用逗号分隔的参数列表。也就是说,你可
以传递几个守卫并用逗号分隔它们。
 
控制器范围注册:
 
全局范围注册:
全局守卫用于整个应用程序 , 每个控制器和每个路由处理程序。在依赖注入方面 , 从任何模块外部注册的全局守卫 ( 如上面的示例中所
) 不能插入依赖项 , 因为它们不属于任何模块。为了解决此问题 , 您可以使用以下构造直接从任何模块设置一个守卫 :
 
 
 

反射器

如果我们利用守卫做权限管理的话,将会出现问题,比如不知道角色,或者程序允许哪些角色,例如我们为不同的路由提供不同的权
限方案,其中,一些可能只对管理用户可用,而另一些则可以对所有人开放。我们如何以灵活和可重用的方式将角色与路由匹配起来 ?
 
利用自定义元数据就可以发挥作用, Nest 提供了通过 SetMetadata() 装饰器将定制的元数据附加到路由。
 

自定义角色装饰器(decorator

通过上面的构建,我们将 roles 元数据 (roles 是一个键,而 [‘admin’] 是一个特定的值 ) 附加到 create() 方法。 直接使用 @SetMetadata()
并不是一个好习惯。 相反,我们应该创建自己的装饰器。
 

权限守卫-RolesGuard

为了访问路由的角色(自定义元数据),我们将使用在 @nestjs/core 中提供的 Reflector 帮助类。

拦截器

拦截器是使用 @Injectable() 装饰器注解的类。拦截器应该实现 NestInterceptor 接口。
 
拦截器具有一系列有用的功能,这些功能受面向切面编程( AOP )技术的启发。它们可以:
 
在函数执行之前 / 之后绑定额外的逻辑
 
转换从函数返回的结果
 
转换从函数抛出的异常
 
扩展基本函数行为
 
根据所选条件完全重写函数 ( 例如 , 缓存目的 )
 

定义拦截器interceptor

使用拦截器在函数执行之前或之后添加额外的逻辑。当我们要记录与应用程序的交互时,它很有用,例如 存储用户调用,异步调度事
件或计算时间戳。
 
由于 handle() 返回一个 RxJS Observable ,我们有很多种操作符可以用来操作流。在上面的例子中,我们使用了 tap() 运算符,该运算符
在可观察序列的正常或异常终止时调用函数
 

绑定拦截器

为了设置拦截器 , 我们使用从 @nestjs/common 包导入的 @UseInterceptors() 装饰器。与守卫一样 , 拦截器可以是控制器范围内的 , 方法
范围内的或者全局范围内的。
 
全局拦截器用于整个应用程序、每个控制器和每
个路由处理程序。在依赖注入方面 , 从任何模块
外部注册的全局拦截器 ( 如上面的示例中所示 )
法插入依赖项 , 因为它们不属于任何模块。                                     

响应映射

我们已经知道 , handle() 返回一个 Observable 。此流包含从路由处理程序返回的值 , 因此我们可以使用 map() 运算符轻松地对其进行改变。
 
让我们创建一个 TransformInterceptor, 它将打包响应并将其分配给 data 属性。
 
返回值(假设返回的是一个 any[] ):
拦截器在创建用于整个应用程序的可重用解决方案时具有巨大的潜力。例如,我们假设我们需要将每个发生的 null 值转换为空字符串 ''
我们可以使用一行代码并将拦截器绑定为全局代码。由于这一点,它会被每个注册的处理程序自动重用
 
 

超时处理

处理路由超时,如果客户端在一段时间后未返回任何内容,将以错误响应终止
 
5m 后,请求将被取消

Nest生命周期

所有应用程序元素都有一个由 Nest 管理的生命周期。
Nest 提供了生命周期钩子,提供了对关键生命时刻的可
见性,以及在关键时刻发生时采取行动 ( 在你的 module
injectable 或者 controller 中注册代码 ) 的能力。
 
下图描述了关键应用生命周期事件序列,从应用引导之
时到 node 应用退出。我们可以把整个生命周期划分为三
个阶段:初始化,运行和终止。使用生命周期,你可以
合理计划模块和服务的初始化,管理活动链接,并且在
应用程序收到终止指令时优雅地退出。
 
 

生命周期事件

 
生命周期事件在应用初始化与终止时发生。 Nest modules injectables controllers 的以下每个生命周期事件中调用注册钩子方法。
和上图所示的一样, Nest 也调用合适的底层方法来监听连接,以及终止监听连接。
 
 
 
请求生命周期
 
 
Nest 应用程序处理请求并生成响应的过程被称为请求生命周期,使用中间件、管道、守卫和拦截器时,要在请求生命周期中追踪特
定的代码片段的执行很困难,尤其是在全局、控制器或者路由的部件中。一般来说,一个请求流经中间件、守卫与拦截器,然后
到达管道,并最终回到拦截器中的返回路径中(从而产生响应)。
 
一般来说,请求生命周期大致如下:
 
1. 收到请求
2. 全局绑定的中间件
3. 模块绑定的中间件
4. 全局守卫
5. 控制层守卫
6. 路由守卫
7. 全局拦截器
(控制器之前)
8. 控制器层拦截器 (控制器之前) 9. 路由拦截器 (控制器之前)
10. 全局管道
11. 控制器管道
12. 路由管道
13. 路由参数管道
14. 控制器(方法处理器)
15. 服务(如果有)
16. 路由拦截器(请求之后)
17. 控制器拦截器 (请求之后) 18. 全局拦截器 (请求之后)
19. 异常过滤器 (路由,之后是控制器,之后是全局)
20. 服务器响应

 

 

集成swagger

现如今,前后端分离已经逐渐成为互联网项目一种标准的开发方式,前端与后端交给不同的人员开发,
 
但是项目开发中的沟通成本也随之升高,这部分沟通成本主要在于前端开发人员与后端开发人员对 WebAPI 接口的沟通, Swagger 就可以很
好地解决,它可以动态生成 Api 接口文档,降低沟通成本,促进项目高效开发。
 
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
 
nest 中使用 swagger ,需要安装相关的依赖
 
npm install --save @nestjs/swagger swagger-ui-express
 
main.ts 中引入对应的配置
 
 

使用swagger

字段使用
@ApiProperty({description:' 创建的时间 ', example:'2021-08-09 21:08:08‘})
 
控制器使用
  @ApiTags(' 购物车模块 ’)
 
路由使用
  @ApiOperation({ summary:' 添加购物车 '})
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值