Nodejs 第四十二章(jwt)

news2025/3/2 2:03:00

什么是jwt?

JWT(JSON Web Token)是一种开放的标准(RFC 7519),用于在网络应用间传递信息的一种方式。它是一种基于JSON的安全令牌,用于在客户端和服务器之间传输信息。 https://jwt.io/

JWT由三部分组成,它们通过点(.)进行分隔:

  1. Header(头部):包含了令牌的类型和使用的加密算法等信息。通常采用Base64编码表示。
  2. Payload(负载):包含了身份验证和授权等信息,如用户ID、角色、权限等。也可以自定义其他相关信息。同样采用Base64编码表示。
  3. Signature(签名):使用指定的密钥对头部和负载进行签名,以确保令牌的完整性和真实性。

JWT的工作流程如下:

  1. 用户通过提供有效的凭证(例如用户名和密码)进行身份验证。
  2. 服务器验证凭证,并生成一个JWT作为响应。JWT包含了用户的身份信息和其他必要的数据。
  3. 服务器将JWT发送给客户端。
  4. 客户端在后续的请求中,将JWT放入请求的头部或其他适当的位置。
  5. 服务器在接收到请求时,验证JWT的签名以确保其完整性和真实性。如果验证通过,服务器使用JWT中的信息进行授权和身份验证。

用到的依赖

  1. passport passport是一个流行的用于身份验证和授权的Node.js库
  2. passport-jwt Passport-JWT是Passport库的一个插件,用于支持使用JSON Web Token (JWT) 进行身份验证和授权
  3. jsonwebtoken 生成token的库

代码编写

沿用上一章的代码 增加jwt目录
上一章代码

image.png

src/jwt/index.ts

import { injectable } from 'inversify'
import jsonwebtoken from 'jsonwebtoken'
import passport from 'passport'
import { Strategy, ExtractJwt } from 'passport-jwt'
@injectable()
export class JWT {
    private secret = 'xiaoman$%^&*()asdsd'
    private jwtOptions = {
        jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
        secretOrKey: this.secret
    }
    constructor() {
        this.strategy()
    }

    /**
     * 初始化jwt
     */
    public strategy() {
        const strategy = new Strategy(this.jwtOptions, (payload, done) => {
            done(null, payload)
        })
        passport.use(strategy)
    }

    /**
     * 
     * @returns 中间件
     */
    public middleware() {
        return passport.authenticate('jwt', { session: false })
    }

    /**
     * 创建token
     * @param data Object
     */
    public createToken(data: object) {
        //有效期为7天
        return jsonwebtoken.sign(data, this.secret, { expiresIn: '7d' })
    }

    /**
     * 
     * @returns 集成到express
     */
    public init() {
        return passport.initialize()
    }
}

main.ts

import 'reflect-metadata'
import { InversifyExpressServer } from 'inversify-express-utils'
import { Container } from 'inversify'
import { User } from './src/user/controller'
import { UserService } from './src/user/services'
import express from 'express'
import { PrismaClient } from '@prisma/client'
import { PrismaDB } from './src/db'
import { JWT } from './src/jwt'
const container = new Container()
/**
 * user模块
 */
container.bind(User).to(User)
container.bind(UserService).to(UserService)
/**
 *  封装PrismaClient
 */
container.bind<PrismaClient>('PrismaClient').toFactory(() => {
    return () => {
        return new PrismaClient()
    }
})
container.bind(PrismaDB).to(PrismaDB)
/**
 * jwt模块
 */
container.bind(JWT).to(JWT) //主要代码


const server = new InversifyExpressServer(container)
server.setConfig((app) => {
    app.use(express.json())
    app.use(container.get(JWT).init()) //主要代码
})
const app = server.build()

app.listen(3000, () => {
    console.log('Listening on port 3000')
})

src/user/controller.ts

import { controller, httpGet as GetMapping, httpPost as PostMapping } from 'inversify-express-utils'
import { UserService } from './services'
import { inject } from 'inversify'
import type { Request, Response } from 'express'
import { JWT } from '../jwt'
const {middleware}  = new JWT()
@controller('/user')
export class User {
    constructor(@inject(UserService) private readonly UserService: UserService) {

    }
    @GetMapping('/index',middleware()) //主要代码
    public async getIndex(req: Request, res: Response) {
        let result = await this.UserService.getList()
        res.send(result)
    }

    @PostMapping('/create')
    public async createUser(req: Request, res: Response) {
        let result = await this.UserService.createUser(req.body)
        res.send(result)
    }
}

src/user/services.ts

import { injectable, inject } from 'inversify'
import { PrismaDB } from '../db'
import { UserDto } from './user.dto'
import { plainToClass } from 'class-transformer'
import { validate } from 'class-validator'
import { JWT } from '../jwt'
@injectable()
export class UserService {
    constructor(
        @inject(PrismaDB) private readonly PrismaDB: PrismaDB,
        @inject(JWT) private readonly jwt: JWT //依赖注入
    ) {

    }
    public async getList() {
        return await this.PrismaDB.prisma.user.findMany()
    }

    public async createUser(user: UserDto) {
        let userDto = plainToClass(UserDto, user)
        const errors = await validate(userDto)
        if (errors.length) {
            return errors
        } else {
            const result = await this.PrismaDB.prisma.user.create({
                data: user
            })
            return {
                ...result,
                token: this.jwt.createToken(result) //生成token
            }
        }

    }
}

哪个接口需要token验证就往哪儿加就可以了

  • 验证失败展示(未携带token)

image.png

  • 验证成功展示(携带token)

image.png

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

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

相关文章

FL Studio All Plugins Edition2024中文完整版Win/Mac

FL Studio All Plugins Edition&#xff0c;常被誉为数字音频工作站&#xff08;DAW&#xff09;的佼佼者&#xff0c;是音乐制作人和声音工程师钟爱的工具。它集音频录制、编辑、混音以及MIDI制作为一体&#xff0c;为用户提供了从创作到最终作品输出的完整工作流程。这个版本…

下载huggingface数据集到本地并读取.arrow文件遇到的问题

文章目录 1. 524MB中文维基百科语料&#xff08;需要下载的数据集&#xff09;2. 下载 hugging face 网站上的数据集3. 读取 .arrow 文件报错代码4. 纠正后代码 1. 524MB中文维基百科语料&#xff08;需要下载的数据集&#xff09; 2. 下载 hugging face 网站上的数据集 要将H…

CrossOver24破解版下载安装与激活

在 Mac 上运行Windows 软件&#xff0c;CrossOver Mac 可以轻松地从 Dock 本地启动 Windows 应用程序&#xff0c;并将 Mac 操作系统功能&#xff08;如跨平台复制和粘贴以及共享文件系统&#xff09;集成到您的 Windows 程序中。 CrossOver 产品特性 无需重启 CrossOver 可以…

python Matplotlib Tkinter(pack)-->最大化去掉,仅剩关闭按钮

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 pillow 10.1.0 import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk import tkinter as tk import tkinter.messagebox as messagebox import …

C/C++基础语法

C/C基础语法 文章目录 C/C基础语法头文件经典问题秒数转换闰年斐波那契数列打印n阶菱形曼哈顿距离菱形图案的定义大数计算 输入输出格式化输入输出getline()函数解决cin只读入一个单词的问题 运算符赋值运算符 Switch循环处理未知数量输入的几种常见方法for-each 字符串String字…

Dell Vestro 7500 Realtek ALC236 耳机插入无效无声音 解决

查了很多&#xff0c;试了很多。 最终还下是重启设备来得最简单有效。 无效方式&#xff1a; 安装最新驱动&#xff1a;没有236这个芯片&#xff0c;找不到官方驱动使用旧驱动&#xff1a;问题依旧使用驱动程序中的禁用设备&#xff0c;启用后还是没有&#xff08;以前好像也…

Kubernetes部署及运用

Kubernetes 1. Kubernetes介绍 1.1 应用部署方式演变 在部署应用程序的方式上&#xff0c;主要经历了三个时代&#xff1a; 传统部署&#xff1a;互联网早期&#xff0c;会直接将应用程序部署在物理机上 优点&#xff1a;简单&#xff0c;不需要其它技术的参与 缺点&#xf…

2024程序员容器化上云之旅-第4集-Ubuntu-WSL2-Windows11版:夺取宝剑

故事梗概 Java程序员马意浓在互联网公司维护老旧电商后台系统。 渴望学习新技术的他在工作中无缘Docker和K8s。 他开始自学Vue3并使用SpringBoot3完成了一个前后端分离的Web应用系统&#xff0c;并打算将其用Docker容器化后用K8s上云。 6 夺取宝剑 &#x1f525;阅读Nigel…

【Vue3】学习watch监视:深入了解Vue3响应式系统的核心功能(下)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

二叉树进阶oj练习

目录 1. 根据二叉树创建字符串 1&#xff09;思路 2&#xff09;代码实现 2. 二叉树前序非递归遍历实现 1&#xff09;思路&#xff1a; 2&#xff09;代码实现 3. 二叉树中序非递归遍历实现 1&#xff09;思路&#xff1a; 2&#xff09;代码实现&#xff1a; 4. 二…

Programming Abstractions in C阅读笔记:p303-p305

《Programming Abstractions in C》学习第74天&#xff0c;p303-p305总结&#xff0c;总计3页。 一、技术总结 1.时间复杂度分类(complexity classes) ClassNotationExampleconstantO(1)Returning the first element in an arraylogarithmicO(logN)Binary search in a sorte…

三菱plc控制双控电磁阀(从接线到程序)

目录 硬件设备 电磁阀的类型&#xff08;下图为例&#xff09; 三菱plc的类型&#xff08;西门子控正COOM接接正极&#xff0c;三菱控负COM接负极&#xff09; 气缸图 三菱plc与双控电磁阀接线 输出接线图&#xff08;COOM输出的公共端&#xff0c;三菱控负COM接负极&#x…

大学生课程|统计基础与python分析6|主流的评估方法:ROC曲线和KS曲线(免费下载所有课程材料)

目录 1 ROC曲线 2.查看混淆矩阵 3.实战评估股票客户流失预警模型 4.阈值的取值方法 5.KS曲线与KS值 6.获取KS值对应的阈值 7.获取KS值 对于二分类模型来说&#xff0c;主流的评估方法有ROC曲线和KS曲线两种方法 1 ROC曲线 之前已经获得了模型的准确度为79.77%&#xf…

【USENIX论文阅读】Day2

Birds of a Feather Flock Together: How Set Bias Helps to Deanonymize You via Revealed Intersection Sizes&#xff08;"物以类聚&#xff1a;集合偏差如何帮助去匿名化——通过揭示交集大小&#xff09; Xiaojie Guo, Ye Han, Zheli Liu, Ding Wang, Yan Jia, Jin L…

高级光线传播与高级外观建模

一.高级光线传播 1、无偏的 ①有偏VS无偏 蒙特卡洛估计出的结果的期望永远是对的 eg&#xff1a;PT中不管有多少样本&#xff0c;期望都是定积分的值 有偏的&#xff1a;估计出的结果的期望和积分的值不一样 一个特殊情况&#xff08;一致的&#xff09;&#xff1a;极限定…

【web APIs】1、(学习笔记)有案例!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、概念二、使用步骤1.获取DOM对象2.操作元素内容3.属性修改3.1.常用属性修改3.2.控制样式属性3.3.操作类名(className) 操作CSS3.4.操作表单元素属性3.5.自定…

Mysql常见函数和用法(重点)

where子句中经常使用的运算符 -- 查询总分大于200分的所有同学 select * from student2 where (chineseenglishmath)>200; -- 查询math大于60 并且(and)id大于4的学生成绩 select * from student2 where math>60 and id>4; -- 查询英语成绩大于语文成绩的同学 select …

面试总结之JVM入门

文章目录 &#x1f412;个人主页&#x1f3c5;JavaEE系列专栏&#x1f4d6;前言&#xff1a;&#x1f380;你为什么要学习JVM&#xff1f;&#x1f380;JVM的作用 &#x1f380;JVM的构成&#xff08;5大类&#xff09;&#x1f3e8;1.类加载系统&#x1f415;类什么时候会被加…

《Docker 简易速速上手小册》第2章 容器和镜像(2024 最新版)

文章目录 2.1 理解 Docker 容器2.1.1 重点基础知识2.1.2 重点案例&#xff1a;使用 Docker 运行 Python 应用2.1.3 拓展案例 1&#xff1a;Docker 中的 Flask 应用2.1.4 拓展案例 2&#xff1a;Docker 容器中的数据分析 2.2 创建与管理 Docker 镜像2.2.1 重点基础知识2.2.2 重点…

k8s(5)

目录 使用Kubeadm安装k8s集群&#xff1a; 初始化操作&#xff1a; 每台主从节点&#xff1a; 升级内核&#xff1a; 所有节点安装docker &#xff1a; 所有节点安装kubeadm&#xff0c;kubelet和kubectl&#xff1a; 修改了 kubeadm-config.yaml&#xff0c;将其传输给…