nestjs守卫/全局守卫校验jwt

一、守卫

目标

部分接口需要用户登录后才可以访问,用户登录后可以颁发 jwt_token 给前端,前端在调用需要鉴权的接口,需要在请求头添加 jwt_token,后端校验通过才能继续访问,否则返回403无权访问

创建守卫 anth

安装依赖
npm i @nestjs/jwt -S
配置 jwt 常量参数 constants/index.ts
// jwt秘钥,固定随机字符串
export const JWT_SECRET = "NODE_TEST_SECRET";// jwt有效期 Eg: "60s", "3h", "2d"
export const JWT_EXPIRES = "2h"; // 2小时
创建 auth 模块 auth/auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { JWT_SECRET, JWT_EXPIRES } from '../constants';@Module({imports: [JwtModule.register({secret: JWT_SECRET, // jwt秘钥signOptions: {expiresIn: JWT_EXPIRES, // jwt有效期}})],providers: [AuthService],exports: [AuthService]
})
export class AuthModule {}
创建 auth 服务 auth/auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';@Injectable()
export class AuthService {constructor(private readonly jwtService: JwtService) {}// 创建jwt_tokenasync createToken(userInfo) {// 将用户信息(userId、name)存放到 jwt 中return {access_token: this.jwtService.sign(userInfo)};}// 校验登录状态validateToken(token) {if (!token) {return false;}try {return this.jwtService.verify(token);} catch {return false;}}
}
创建 auth 守卫 auth/auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { AuthService } from './auth.service';@Injectable()
export class AuthGuard implements CanActivate {constructor(private authService: AuthService) {}canActivate(context: ExecutionContext) {const request = context.switchToHttp().getRequest();const token = request.headers['authorization']; // 从请求头中获取 tokenif (!token) {return false;} else {return this.authService.validateToken(token); // 如果 token 有效,返回 true,允许访问资源}}
}

使用守卫 auth

需要鉴权的模块添加 auth 模块

api.module.ts

...
import { AuthModule } from '../auth/auth.module';@Module({imports: [AuthModule],...
})
export class ApiModule {}
需要鉴权的接口引入守卫

api.controller.ts

...
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from '../auth/auth.guard';@Controller('api')
export class ApiController {constructor(private readonly apiService: ApiService) {}@Get('getUserInfo')@UseGuards(AuthGuard) // 需要鉴权的接口添加UseGuardsgetUserInfo(): any {return this.apiService.getUserInfo();}
}
登录

调用 auth/auth.service.ts 中的 createToken 生成 jwt_token 返回给前端

前端在请求头添加 authorization

如果请求头没有 authorization,或者 authorization 失效,则返回 403 Forbidden

二、全局守卫

目标

由于单个守卫需要引入守卫模块、守卫方法,并且针对每一个接口加 @UseGuards 装饰器,使用起来比较繁琐。项目中经常遇到非常多的接口都需要鉴权,所以就需要使用全局守卫来校验需要鉴权的接口。

注意:获取与解析 jwt_token 的方法上面守卫的方法一致,auth/auth.service,此处不再赘述。

创建全局守卫

配置需要鉴权的接口常量 constants/index.ts
// 需要校验 jwt 的 url 列表
export const ValidUrlList = ['/api/getUserInfo','/api/product/buy','/api/queryUserWallet'
];
新建全局守卫 global.guard.ts
import { Injectable, NestInterceptor, ExecutionContext, HttpException, HttpStatus } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { AuthService } from './auth/auth.service';
import { ValidUrlList } from './constants';@Injectable()
export class GlobalGuard implements NestInterceptor {constructor(private authService: AuthService) {}intercept(context: ExecutionContext, next): Observable<any> {// 在这里执行全局守卫逻辑const request = context.switchToHttp().getRequest();// 从请求头中获取 tokenconst token = request.headers['authorization'];// 请求的url,用于判断是否需要校验jwtconst url = request.url;if (ValidUrlList.includes(url)) {// 需要鉴权才能访问的接口const validRes = this.authService.validateToken(token);if (!validRes) {return next.handle().pipe(map(() => {// 如果没有提供令牌,返回错误响应或执行其他逻辑return new HttpException('Forbidden', HttpStatus.FORBIDDEN);}));}}// 不需要校验的接口、校验通过的接口直接放行return next.handle();}
}

在 app.module.ts 配置全局守卫

// ...
import { APP_INTERCEPTOR } from '@nestjs/core';
import { JwtModule } from '@nestjs/jwt';
import { GlobalGuard } from './global.guard';
import { JWT_SECRET, JWT_EXPIRES } from './constants';
import { AuthService } from './auth/auth.service';@Module({imports: [JwtModule.register({secret: JWT_SECRET, // jwt秘钥signOptions: {expiresIn: JWT_EXPIRES, // jwt有效期}}),],providers: [{provide: APP_INTERCEPTOR,useClass: GlobalGuard,},AuthService],
})
export class AppModule {}

三、swagger文档调用需要鉴权的接口

目标

接口添加 jwt 鉴权后,接口文档调用接口请求头没有添加 authorization,请求会返回403。为此,需要给文档需要鉴权的接口请求头也添加 authorization

步骤

main.ts 配置 BearerAuth 校验
const config = new DocumentBuilder().setTitle('接口文档').setDescription('接口文档描述').setVersion('1.0').addBearerAuth() // 注意此处:文档添加BearerAuth.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api-docs', app, document);
在需要鉴权的接口添加 @ApiBearerAuth() 装饰器
import { ApiBearerAuth } from '@nestjs/swagger';@Controller('api')
@ApiBearerAuth() // 在此处添加,表示/api/的接口请求头全都需要添加authorization
export class ApiController {@Get('getUserInfo')@UseGuards(AuthGuard)@ApiBearerAuth() // 在此处添加,表示当前接口请求头需要添加authorizationgetUserInfo(): any {return this.apiService.getUserInfo();}
}
使用

先调用登录接口获取到 jwt_token

点击文档顶部Authorize按钮

输入获取到的 jwt_token,并点击Authorize,然后关闭弹窗

再调用需要鉴权的接口,就可以鉴权通过了

注意:请求头的 Authorization 参数会在最前面添加 Bearer 字符,可以在守卫中将此字符移除

this.jwtService.verify(token.replace('Bearer ', ''))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/221177.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql:不要在索引列进行数学运算和函数运算

不要在索引列进行数学运算和函数运算。这是因为数学运算和函数运算会改变索引列的值&#xff0c;导致索引失效。 如果需要进行计算或函数处理&#xff0c;最好将数据取出并在应用程序中进行处理。 下面举个对照的例子&#xff1a; 1&#xff09;看语句explain select * from …

注塑模具ERP有哪些功能?可以帮助企业解决什么难题

不同的注塑模具有不同的业务流程和生产环节&#xff0c;有些生产企业在订单、物料需求计划、车间、班组负荷评估、项目成本核算、边角料统计分析等方面还存在不少问题。 与此同时&#xff0c;也有部分注塑模具企业通过ERP软件科学制定注塑生产排产&#xff0c;智能核算注塑物料…

用print太慢了!强烈推荐这款Python Debug工具~

作为程序员&#xff0c;我们都深知调试&#xff08;Debug&#xff09;在编程过程中的重要性。然而&#xff0c;使用传统的"print"语句进行调试可能效率较低&#xff0c;今天&#xff0c;笔者将推荐一款独具一格的Python调试工具——Reloadium。Reloadium为IDE添加了热…

深入理解Spring Security授权机制原理

原创/朱季谦 在Spring Security权限框架里&#xff0c;若要对后端http接口实现权限授权控制&#xff0c;有两种实现方式。 一、一种是基于注解方法级的鉴权&#xff0c;其中&#xff0c;注解方式又有Secured和PreAuthorize两种。 Secured如&#xff1a; 1 PostMapping("…

elementui select中添加新增标签

<el-select v-model"ruleForm.eventType" :placeholder"请选择事件类型&#xff0c;可手动添加" ref"template" clearable visible-change"(v) > visibleChange(v, template)"><el-option v-for"item in eventTypeOp…

【论文极速读】视频检索中的模态均衡方法

【论文极速读】视频检索中的模态均衡方法 FesianXu 20231206 at Baidu Search Team 前言 传统的视频搜索系统相关性部分主要以文本匹配为基础手段&#xff0c;在其中引入多模态向量容易收到『模态不均衡』的问题&#xff0c;论文[1]尝试对其进行解决&#xff0c;本文进行笔记。…

02markdown-学习笔记

一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 换行符<br>标签 写入一段测试用的正文第二段测试文本,如果要对文本进行换行可以使用<br>标签 文本修饰符 字体为斜体的修饰&#xff0c;一对星号包含 字符为粗体&#xff0c;两对星号包含 字体为…

如何定位线上OOM?

文章目录 造成OOM的原因1.一次性申请的太多2. 内存资源耗尽未释放3.本身资源不够 如何快速定位OOM&#xff1f;1.系统已经OOM了2.系统运行中还未OOM2.1导出dump文件&#xff1a;2.2.结合jvisualvm进行调试2.3 利用ArthasArthas可以做什么&#xff1f;如何使用Arthas小结 造成OO…

【带头学C++】----- 九、类和对象 ---- 9.13 运算符重载——(9.13.7-9.13.8)

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️创做不易&#xff0c;麻烦点个关注❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ ❤️❤️❤️❤️❤️❤️❤️❤️❤️文末有惊喜&#xff01;献舞一支&#xff01;❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ 目录 9.13…

Git篇---第九篇

系列文章目录 文章目录 系列文章目录前言一、使用过git merge和git rebase吗?它们之间有什么区别?二、使用过git cherry-pick,有什么作用?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看…

GPIO模拟MDIO

背景 CPU&#xff1a;AST2500 驱动里实现GPIO模拟MDIO驱动,参考内核驱动mdio-bitbang.c和mdio-gpio.c&#xff0c;当前项目不支持设备树&#xff0c;驱动需要改成platform注册 MDIO介绍 SMI接口 SMI是MAC内核访问PHY寄存器接口&#xff0c;它由两根线组成&#xff0c;双工…

c++ qt 窗口开发中 俩按钮组合 配合 显影 已解决

在日常项目中&#xff0c;有这么需求&#xff0c;还想窗口移动&#xff0c;还想 右侧关闭 还能tab栏点击显影的需求&#xff0c;不得使用 qt模拟点击事件 进行功能优化 特大杯 大杯 控制 窗口显影&#xff0c; 咖啡 按钮 显示窗口 可乐 豆浆 不显示窗口 四个按钮的 互斥关…

Amazon SageMaker机器学习之旅的助推器

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 一、前言 在当今的数字化时代&#xff0c;人工智能和机器学习已经…

2023一起益企广东省中小企业数字化赋能活动(深圳站)成功举办

12月12日&#xff0c;由广东工业和信息化厅指导&#xff0c;广东省中小企业服务中心、深圳市中小企业服务局主办&#xff0c;深圳联通承办的2023年“一起益企”广东省中小企业数字化赋能专项对接志愿服务活动&#xff08;深圳站&#xff09;在深圳成功举办。 本次活动涵盖中小企…

【AI底层逻辑】——“数学华尔兹”之一元线性回归

一元线性回归模型想必大家都耳熟能详&#xff0c;这里不再赘述。但在使用python中机器学习包时一定见过类似模型评价参数的输出&#xff0c;这一章我们就讲一讲回归分析里一些模型评价概念&#xff01; 一、方差分析ANOVA 方差分析是一种用于确定线性回归模型中不同变量对目标…

【改进YOLOv8】车辆测距预警系统:融合空间和通道重建卷积SCConv改进YOLOv8

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义&#xff1a; 随着交通工具的普及和道路交通的不断增加&#xff0c;车辆安全问题日益凸显。特别是在高速公路等高速道路上&#xff0c;车辆之间的距离和速度差异较…

【论文】 虚拟机 和 Linux容器 的 最新性能比较

虚拟机 和 Linux容器 的 最新性能比较 An Updated Performance Comparison of Virtual Machines and Linux Containers 借助DeepL辅助翻译 校准 摘要 云计算广泛使用虚拟机&#xff08;VM&#xff09;&#xff0c;因为它们允许工作负载相互隔离&#xff0c;并在一定程度上控…

springboot框架的客制化键盘个性化商城网站

客制化键盘网站是从客制化键盘的各部分统计和分析&#xff0c;在过程中会产生大量的、各种各样的数据。本文以客制化键盘管理为目标&#xff0c;采用B/S模式&#xff0c;以Java为开发语言&#xff0c;Jsp为开发技术、idea Eclipse为开发工具&#xff0c;MySQL为数据管理平台&am…

西南科技大学数字电子技术实验七(4行串行累加器设计及FPGA实现)FPGA部分

一、实验目的 1、掌握基于Verilog语言的diamond工具设计全流程。 2、熟悉、应用Verilog HDL描述数字电路。 3、掌握Verilog HDL的组合和时序逻辑电路的设计方法。 4、掌握“小脚丫”开发板的使用方法。 二、实验原理 三、程序清单&#xff08;每条语句必须包括注释或在开发…

Leetcode 491 递增子序列

题意理解&#xff1a; 输入&#xff1a;nums [4,6,7,7] 输出&#xff1a;[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]] 这里不止要找一个子序列&#xff0c;还要元素保证其在原来的集合中的前后顺序&#xff0c;且应为增序。 为保证一个增序序列&#xff0c;…