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_token
  async 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']; // 从请求头中获取 token
    if (!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) // 需要鉴权的接口添加UseGuards
  getUserInfo(): 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();
    // 从请求头中获取 token
    const token = request.headers['authorization'];
    // 请求的url,用于判断是否需要校验jwt
    const 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 {}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java.lang.NegativeArraySizeException

构建maven项目时发生的异常 maven-resources-production:gci-system-start:java.lang.NegativeArraySizeException:-1972174848解决方案 先将 target 目录删除,然后重新构建项目即可

【从零开始学习JVM | 第九篇】了解 常见垃圾回收器

前言&#xff1a; 垃圾回收器&#xff08;Garbage Collector&#xff09;是现代编程语言中的一项重要技术&#xff0c;它提供了自动内存管理的机制&#xff0c;极大地简化了开发人员对内存分配和释放的繁琐工作。通过垃圾回收器&#xff0c;我们能够更高效地利用计算机的内存资…

基于pandoraNext使用chatgpt4

1.登陆GitHub 获取pandoraNext项目GitHub - pandora-next/deploy: Pandora Cloud Pandora Server Shared Chat BackendAPI Proxy Chat2API Signup Free PandoraNext. New GPTs(Gizmo) UI, All in one! 在release中选择相应版本操作系统的安装包进行下载 2.获取license_…

【OS】操作系统总复习笔记

操作系统总复习 文章目录 操作系统总复习一、考试题型1. 论述分析题2. 计算题3. 应用题 二、操作系统引论&#xff08;第1章&#xff09;2.1 操作系统的发展过程2.2 操作系统定义2.3 操作系统的基本特性2.3.1 并发2.3.2 共享2.3.3 虚拟2.3.4 异步 2.4 OS的功能2.5 OS结构2.5 习…

聊聊Java中的常用类String

String、StringBuffer、StringBuilder 的区别 从可变性分析 String不可变。StringBuffer、StringBuilder都继承自AbstractStringBuilder &#xff0c;两者的底层的数组value并没有使用private和final修饰&#xff0c;所以是可变的。 AbstractStringBuilder 源码如下所示 ab…

鸿蒙ArkTS Web组件加载空白的问题原因及解决方案

问题症状 初学鸿蒙开发&#xff0c;按照官方文档Web组件文档《使用Web组件加载页面》示例中的代码照抄运行后显示空白&#xff0c;纠结之余多方搜索后扔无解决方法。 运行代码 import web_webview from ohos.web.webviewEntry Component struct Index {controller: web_webv…

MuMu模拟器12如何连接adb?

一、MuMu模拟器12端口查看 MuMu模拟器12现已支持adb同时连接多个模拟器进行调试的操作&#xff0c;可以参考以下步骤操作&#xff0c;查看MuMu模拟器12本体以及多开模拟器的adb端口&#xff1a; 单开的MUMU模拟器12可通过模拟器右上角菜单-问题诊断&#xff0c;获取ADB调试端…

VM-Linux 桥接网络设置

VM-Linux 桥接网络设置 文章目录 VM-Linux 桥接网络设置什么是桥接网络环境工具关键配置VM设置CentOS7配置 什么是桥接网络 网络桥接是将两个或多个独立的网络进行连接的一种方法。它可以把两个网络的数据传输机制集成在一起&#xff0c;使得用户可以更顺畅地访问各个网络&…

Linux实操——安装Mysql

安装Mysql 一、检查是否已经安装了mariadb数据库,并卸载二、下载mysql包&#xff0c;并通过ftp上传到服务器三、解压安装包四、创建数据存储文件夹五、创建执行mysqld命令的用户&#xff0c;并初始化mysql六、启用传输安全七、启动mysql&#xff0c;验证是否安装成功 总结 博主…

stm32F407-GPIO的使用——点亮LED并且讲解各个寄存器

stm32F407-GPIO的使用——点亮LED并且讲解各个寄存器 本文为stm32GPIO的介绍与使用&#xff0c;例子是简单的LED点亮。 一、 GPIO GPIO&#xff08;General Purpose I/O Ports&#xff09;意思为通用输入/输出端口&#xff0c;通俗地说&#xff0c; 就是一些引脚&#xff0c;可…

数据结构第六课 -------迭代排序(快速排序和归并排序)

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

linux 调试工具 GDB 使用

gdb是linux下常用的代码调试工具&#xff0c;本文记录常用命令。 被调试的应用需要使用 -g 参数进行编译&#xff0c;如不确定可使用如下命令查看是否支持debug readelf -S filename | grep "debug" 启动调试 gdb binFile 例如要调试sshd&#xff1a; 调试带参数…

【淘宝网消费类电子产品销售数据可视化】

淘宝网消费类电子产品销售数据可视化 引言数据爬取与处理数据可视化系统功能1. 总数据量分析2. 店铺总数据3. 店铺销售额排名4. 不同电子商品销售价格5. 单个商品价格排名6. 不同省份平均销量7. 不同地区的平均销售额8. 省份数量9. 每个省份有用的平均个数 创新点结语 引言 随…

平头哥玄铁 E902 编译与使用

玄铁 E902 是平头哥半导体有限公司自主研发的极低功耗、极低成本嵌入式 CPU 核&#xff0c;以 8 位 CPU 的成本获得 32 位嵌入式 CPU 的运行效率与性能。 E902 兼容 RISC-V 指令架构&#xff0c;采用 16/32 位混合编码系统&#xff0c;指令系统与流水线硬件结构精简高效&#x…

单片机的低功耗模式介绍

文章目录 简介一、功耗来源说明1.1、芯片工作模式1.2、静态损耗1.3、I/O额外损耗1.4、动态损耗 二、功耗如何测量三、降低功耗有什么方法3.1、选取合适的芯片工作模式3.2、降低工作频率3.3、关闭不需要使用的外设3.4、 降低静态电流损耗3.5、 周期采集供电3.6、 设置IO口状态 四…

Visual Studio Code (Vscode)配置LaTeX

Visual Studio Code (Vscode)配置LaTeX 实操记录 第一步高效检索&#xff0c;找到官方的、靠谱的安装教程&#xff0c;最好多找几个&#xff0c;英文、中文教程都需要 LaTeX WorkshopInstallation and basic settingsHow to install LaTeX (with previews & autocomplete…

RK3568全国产化多网口板卡带poe供电,支持鸿蒙麒麟系统

信迈XM-3568-01主板采用瑞芯微RK3568四核Cortex-A55 处理器&#xff0c;主频最高可达2.0GHz&#xff0c;效能有大幅提升最高可配8GB内存容量&#xff0c;频率高达1600MHz&#xff1b;支持全链路ECC&#xff0c;让数据更安全可靠配置双千兆自适应RJ45以太网口&#xff0c;并扩展…

ArkTS的状态管理机制(State)

什么是ArkTS的状态管理机制 声明式UI中&#xff0c;是以状态(State)来驱动视图更新的(View)。 状态是指驱动视图更新的数据(被装饰器标记的变量)。 视图是指UI描述渲染得到的用户页面。 互动事件可以改变状态的值。状态改变以后&#xff0c;又会触发事件&#xff0c;渲染页面。…

电子取证中Chrome各版本解密Cookies、LoginData账号密码、历史记录

文章目录 1.前置知识点2.对于80.X以前版本的解密拿masterkey的几种方法方法一 直接在目标机器运行Mimikatz提取方法二 转储lsass.exe 进程从内存提取masterkey方法三 导出SAM注册表 提取user hash 解密masterkey文件&#xff08;有点麻烦不太推荐&#xff09;方法四 已知用户密…

QT作业4

实现一个闹钟&#xff0c;当输入时间后&#xff0c;点击启动到达时间后循环播报三遍&#xff0c;便签内容 头文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTextToSpeech> //文本转语言类 #include <QTimerEvent> //定…