一文带你掌握nestjs的Guard(守卫)

简介: 一文带你掌握nestjs的Guard(守卫)

什么是Guard

image.png


在 Nest.js 中,Guard(守卫)是一种用于保护路由端点的机制。类似于中间件,在请求到达路由处理程序之前,Guard 可以对请求进行拦截并在特定条件下允许或拒绝请求。


可以将 Guard 想象成一个安全守卫或门卫,它会检查进入系统的请求是否符合特定的要求才能通过。通常情况下,Guard 在路由处理程序之前执行,用于验证请求是否具备执行相应操作的权限或满足其他特定条件。这些条件可以是身份验证、授权、角色检查、IP 地址过滤等。


Guard 可以被应用到整个应用程序、模块或具体的路由上。它可以是同步的,也可以是异步的,这取决于你的需求。当 Guard 拦截请求并确定其通过或拒绝时,它可以返回 表示允许请求通过,或者返回一个包含详细错误信息的异常对象来拒绝请求。


通过使用 Guard,你可以确保只有符合特定条件的请求才能访问和操作受保护的资源。这样可以增强应用程序的安全性,并实现更细粒度的权限控制。


总结起来,Nest.js 中的 Guard 就像是一个保安人员,用于在请求到达路由处理程序之前进行检查,并决定请求是否被允许通过。它通过验证身份、权限或其他条件来保护应用程序的资源。


Guard的作用

刚才我们也提到了,Guard在路由处理程序之前执行,用于验证请求是否具备执行相应操作的权限或满足其他特定条件,如果验证通过则放行,验证失败则会拒绝。


能够对身份验证,授权,ip地址过滤等进行处理


注意一点: Guard(守卫)在所有中间件之后执行,但在任何拦截器或管道之前执行。所以它的权限还是比较高的


项目中的应用

Guard基本使用

创建Guard

首先通过命令创建一个Guard

nest g gu auth --no-spec

image.png


每个guard都必须实现一个功能。并且这个函数返回一个布尔值,指示是否允许当前请求。它可以同步或异步返回响应。Nest 使用返回值来控制下一个操作


如果返回true,请求将被处理。

如果它返回false,Nest将拒绝该请求

使用Guard

在要做权限验证的模块的controller中使用@UseGuard()装饰器将类(不是实例)上,将实例化的责任留给了框架并启用依赖注入


image.png


同样,我们也可以直接传递一个实例


image.png


与管道,拦截器,过滤器一样,我们可以将Guard注册为全局的


image.png


全局防护用于整个应用程序,用于每个控制器和每个路由处理程序。在依赖关系注入方面,从任何模块外部注册的全局防护(如上例所示)无法注入依赖关系,因为这是在任何模块的上下文之外完成的,没有从模块中导出或者引入,可以这样处理,来为注入依赖关系


在app根模块中提供


image.png


角色验证案例

元数据

对于不同的路由,可以有不同的权限方案。有些可能仅对管理员用户可用,而另一些可能对所有人开放。我们如何以灵活且可重用的方式将角色与路由匹配?


Nest 提供了通过装饰器将自定义元数据附加到路由处理程序的功能。我们可以通过元数据来对权限进行限制 Nest.js 中的SetMetadata()是一个装饰器工具函数,用于在类、方法或参数上设置自定义的元数据。元数据是与被装饰项(类、方法或参数)相关的任意信息,可以在运行时使用反射和元编程技术进行访问。


image.png


但是这种方式在controller中设置,不灵活,我们可以自定义一个装饰器,通过命令创建一个装饰器


nest g d role --no-spec


image.png

这时候在controller中使用 此方法更清晰、更具可读性,并且是强类型。

image.png

角色校验

上面我们通过设置了路由的元数据,我们将实际功能开放给的用户和路由元数据中的角色进行比较,如果一直就通过,给开放相应的功能,不通过就不开放相应的功能


我们需要从@nestjs/core导入一个Reflector,它能够将路由元数据反射出来,通过constructor构造函数将类注入进去后便可以使用


import { Reflector } from '@nestjs/core';

在守卫(Guard)中, 对象是执行上下文的一个实例,提供了许多有用的方法和属性来访问请求、响应和执行的处理程序信息。其中, getHandler()方法是 对象的一个方法,用于获取当前路由处理程序的引用。我们可以看到返回的是gethello这个函数,也就是我们用于Guard的这个路由方法


通过reflector的get方法能够将路由身上的元数据读取出来


image.png    


接着做逻辑处理


首先获取http请求对象,获取他的角色属性,而后自己封装了一个函数matchRoles来比较角色身份


image.png


我们来做一个小例子来验证一下


image.png


在controller中定义一个post请求,只有身份是admin的才可以访问,否则没有权限


image.png


我们发现报的403没有权限异常, 这是因为 当权限不足的用户请求端点时,Nest 会自动返回以下响应


如果我们要自己设置异常,Guard(守卫)引发的任何异常都将由异常层(全局异常过滤器和应用于当前上下文的异常过滤器)处理。


image.png


当我们请求的对象是admin的时候就可以放行了


总结

Guard在nestjs中还是很重要的,应用场景也很多,这里只拿出简简单单的一个例子帮助大家掌握Guard,写作不易,希望多多支持!

相关文章
|
5天前
|
JavaScript
Vue的vant notify组件报错Notify is not defined
Vue的vant notify组件报错Notify is not defined
|
5天前
|
JavaScript 开发者
Vue中provide和inject的作用是什么?
Vue中provide和inject的作用是什么?
26 0
|
5天前
|
JavaScript
Vue中的provide和inject的使用场景是什么?
Vue中的provide和inject的使用场景是什么?
33 3
|
5天前
Vue3 跨组件传参 provide 与 inject
Vue3 跨组件传参 provide 与 inject
|
3天前
|
设计模式 JavaScript API
Vue.js的provide/inject API实现了依赖注入
【5月更文挑战第17天】Vue.js的provide/inject API实现了依赖注入,允许父组件向深层子组件传递依赖,降低耦合,提高代码可维护性和测试性。通过provide选项提供依赖,如`provide: {foo: 'foo', bar: this.bar}`,子组件通过inject选项接收,如`inject: ['foo', 'bar']`。适用于跨组件共享数据、插件开发和高阶组件。然而,应谨慎使用以防止过度复杂化代码结构。
13 0
|
4天前
|
JavaScript 安全 网络架构
阿珊详解Vue Router的守卫机制
阿珊详解Vue Router的守卫机制
|
5天前
|
JavaScript
vue3的警告问题 [Vue warn]: inject() can only be used inside setup() or functional components. 怎么解决?
vue3的警告问题 [Vue warn]: inject() can only be used inside setup() or functional components. 怎么解决?
84 5
|
5天前
|
JavaScript 前端开发
除了 require.ensure,还有哪些方法可以实现路由懒加载?
除了 require.ensure,还有哪些方法可以实现路由懒加载?
14 1
|
6月前
【异常报错】must call Vue.use(Vuex)
【异常报错】must call Vue.use(Vuex)
|
7月前
|
前端开发
React-Hooks-自定义Hook
React-Hooks-自定义Hook
30 0