JWTの求生记录

article/2025/6/8 3:00:18

Token 三巨头通常指的是三种主流的令牌(Token)技术,它们各自解决了不同场景下的身份验证和授权问题

Token 验证是现代 Web 和移动应用中常用的身份验证方式,它比传统的 session-cookie 机制更适用于分布式系统和 RESTful API。

基本 Token 验证流程

  1. 用户登录:客户端发送用户名和密码到服务器
  2. 服务器验证:验证凭证有效性
  3. 生成 Token:验证通过后生成加密的 token
  4. 返回 Token:将 token 返回给客户端
  5. 后续请求:客户端在请求头中携带 token
  6. 服务器验证 Token:验证 token 有效性并返回数据

常见的 Token 类型

1. JWT (JSON Web Token)

  • 自包含的 token,包含用户信息、过期时间等
  • 由三部分组成:头部(Header),载荷(Payload),签名(Signature)
  • 不需要服务器存储 session
  • 适合前后端分离架构

2. OAuth Token

  • 用于第三方授权
  • 包括 access token 和 refresh token

3. Session Token

  • 传统 session ID 的变种
  • 服务器需要维护 token 状态

从删库到跑路之JWT速成

当前我正在编写一个聊天室项目,已经完成了用户注册,需要对用户登录进行token验证编写,目前采用的方案是JWT方式。

JWT优缺点

优势

  • 适合 RESTful API 和微服务架构
  • 跨语言支持(标准 RFC 7519)
  • 减少服务端存储压力

短板

  • 无法主动废止(需借助黑名单或短有效期)
  • Payload 大小影响网络传输

JWT方式是服务器索性不保存 session 数据了,所有数据都保存在客户端,每次请求都发回服务器。

总结:JWT就像渣男三件套:会自爆(过期)、能续杯(Refresh)、可拉黑(黑名单)

项目框架

  • 前端:Vue3 + Vite
  • 后端:Node.js + Express + Socket.io
  • 数据库:MongoDB

JWT

首先要了解JWT的基本概念:

  1. JWT结构
头部(Header)载荷(Payload)签名(Signature)
算法和令牌类型传递的信息验证令牌的真实性
alg属性表示签名算法,默认是HMAC SHA256typ属性表示这个令牌的类型JWT 规定了7个官方字段,除了官方字段自己也可以定义部分私有字段,JWT默认不加密,不要把秘密信息放在这部分对前两部分的签名,防止数据篡改。需要指定一个密钥,这个密钥只有服务器才知道,不能泄露给用户,然后,使用 Header 里面指定的签名算法算出签名,把Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户

载荷payload官方字段

* iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
  1. 密钥:生成和验证 JWT 时,你需要一个密钥。密钥可以是对称密钥(使用相同的密钥进行签名和验证)或非对称密钥(使用不同的密钥进行签名和验证)。
  2. 签名验证: 接收 JWT 的服务器使用密钥验证签名以确保 JWT 未被篡改。如果签名验证成功,服务器可以信任 JWT 中的信息。

JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
并且JWT本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

实现步骤

实现思路图

在这里插入图片描述

1. 安装依赖
yarn add jsonwebtoken

JsonWebToken中文网:开发文档 | JsonWebToken 中文网

2. 基础生成

services文件夹中创建一个tokenService.js,用于编写与JWT相关的代码。

在这里插入图片描述

可以使用以下代码生成一个基础的token,设置expiresIn过期时间15分钟,以及notBefore10秒后生效:

const jwt = require('jsonwebtoken');/***  获取 JWT 签名密钥*/
const secretKey = 'chat_box_wang_wu';/*** 生成 JWT token* @param {Object} user - 用户信息对象* @returns {string} - 生成的 token*/
const generateToken = (user) => {return jwt.sign(user, secretKey, { expiresIn: '15m', notBefore: '10s' });
};

jwt.sign方法传入的参数:jwt.sign(payload, secretOrPrivateKey, [options, callback])

  • payload: 可以表示有效JSON对象字面量、缓冲区或字符串。
  • secretOrPrivateKey: 是一个字符串(utf-8 编码)、缓冲区、对象或 KeyObject。包含HMAC 算法的密钥或 RSA 和 ECDSA 的 PEM 编码私钥。
  • options:
option常用配置作用说明
expiresIn过期时间以秒为单位表示或描述时间跨度的字符串
notBefore生效时间以秒为单位表示或描述时间跨度的字符串
audience受众
issuer签发人
jwtid编号
subject主题
algorithm算法用来算出签名,默认的HS256算法
3. 用户登录路由

创建用户登录处理方法,然后将此方法挂载到路由当中

loginRouter.get('/login', loginCheck);
/*** 用户登录处理方法* @param {Object} req - 请求对象,包含用户登录信息* @param {Object} res - 响应对象,用于发送响应数据* @returns {Promise<void>} - 一个Promise,用于处理异步操作* @throws {Error} - 如果登录过程中发生错误,将抛出一个错误* */
const loginCheck = async (req, res) => {try {const { username, password } = req.query;const result = await loginService.loginUserExist(username, password);if (result.exists) {const token = generateToken({ username: username, userid: result.userid });res.json({ status: 'success', code: 200, message: '登录成功', token });} else {res.json({ status: 'failure', code: 400, message: '登录失败,用户名或密码错误' });}} catch (error) {res.status(500).json({ error: '服务器错误', code: 500 });console.error(`登录失败: ${error.message}`);}
}

这样就能够使用用户名和密码访问该路由接口,获取到一个JWT生成的token结果

在这里插入图片描述

解码之后的结果:

在这里插入图片描述

4. 验证JWT token

在登陆后请求返回token,需要在服务器上验证其真实性,下面是使用jwt.verify进行验证的方法:

/*** 验证 JWT token* @param {string} token - 待验证的 token* @returns {Object|boolean} - 验证成功返回用户信息,失败返回 false*/
const verifyToken = (token) => {try {return jwt.verify(token, secretKey);} catch (error) {return false;}
};

为了更容易在项目当中使用,可以创建一个配套的验证中间件来保护特定路由:

/*** 验证 token 的中间件* @param {Object} req - 请求对象* @param {Object} res - 响应对象* @param {Function} next - 下一步函数*/
const authMiddleware = (req, res, next) => {// 检查响应是否已发送if (res.headersSent) {return;}const token = req.headers['authorization'];if (!token) {return res.status(401).json({ error: '未提供 token', code: 401 });}try {const user = verifyToken(token.replace('Bearer ', ''));if (!user) {return res.status(403).json({ error: '无效的 token', code: 403 });}req.user = user;next();} catch (error) {return res.status(403).json({ error: '无效的 token', code: 403 });}
};
5. 聊天室创建使用JWT

访问创建聊天室接口,如果当前auth未携带token,返回提示信息,在上一步中已经创建了验证token中间件,将中间件放在创建方法头部

在这里插入图片描述

在这里插入图片描述

提供正确的token后,创建任务就可以成功

在这里插入图片描述

这里利用JWT 解析后的数据,可以判断token中的用户和发送请求的用户是否一致:

	const user = verifyToken(token.replace('Bearer ', ''));if (!user) {return res.status(403).json({ error: '无效的 token', code: 403 });}// 验证请求中的creatorId是否与token中的userid一致if (req.body.creatorId && user.userid && req.body.creatorId !== user.userid) {return res.status(403).json({ error: '无权操作他人数据', code: 403 });}req.user = user;next();

在这里插入图片描述


安全最佳实践

  1. 使用 HTTPS 传输 token
  2. 设置合理的 token 过期时间
  3. 对于敏感操作要求重新认证
  4. 使用 refresh token 机制更新 access token
  5. 防范 CSRF 和 XSS 攻击
  6. 不要在客户端存储敏感信息
  7. 实现 token 黑名单机制(用于注销)

本文并未将JWT实战全部写完,对于token过期处理、多端登录、注销问题、黑名单等常见问题还需后续实践中不断学习,这些问题的解决方案往往需要在安全性、性能和用户体验之间寻找最佳平衡点

在这里插入图片描述


http://www.hkcw.cn/article/wYEaMTsKBq.shtml

相关文章

个人博客系统自动化测试报告

个人博客系统自动化测试报告 文章目录 个人博客系统自动化测试报告1. 项目背景2. 测试内容2.1 编写测试用例2.2 执行测试用例 1. 项目背景 个人博客系统由四个界面组成&#xff1a;博客登录页、博客列表页、博客详情页、博客发布页。通过使用Python Selenium实现web自动测试&a…

2025年人文发展与文化传播国际会议(ICHDCC 2025)

2025年人文发展与文化传播国际会议&#xff08;ICHDCC 2025&#xff09; 2025 International Conference on Humanistic Development and Cultural Communication 一、大会信息 会议简称&#xff1a;ICHDCC 2025 大会地点&#xff1a;中国绵阳 审稿通知&#xff1a;投稿后2-3…

MySQL - Windows 中 MySQL 禁用开机自启,并在需要时手动启动

Windows 中 MySQL 禁用开机自启&#xff0c;并在需要时手动启动 打开服务管理器&#xff1a;在底部搜索栏输入【services.msc】 -> 点击【服务】 打开 MySQL 服务的属性管理&#xff1a;找到并右击 MySQL 服务 -> 点击【属性】 此时的 MySQL 服务&#xff1a;正在运行&a…

「EN 18031」访问控制机制(ACM - 1):智能路由器的安全守卫

家用路由器要是出口欧洲&#xff0c;可得留意欧盟EN18031标准里的访问控制机制。以路由器为例&#xff0c;访问控制机制&#xff08;ACM&#xff09;能决定谁能连入网络、访问哪些网站。比如通过设置不同的用户角色和权限&#xff0c;家长可以限制孩子设备的上网时间和可访问的…

线性动态规划

具有「线性」阶段划分的动态规划方法统称为线性动态规划&#xff08;简称为「线性 DP」&#xff09;&#xff0c;如下图所示。 一、概念 如果状态包含多个维度&#xff0c;但是每个维度上都是线性划分的阶段&#xff0c;也属于线性 DP。比如背包问题、区间 DP、数位 DP 等都属…

如何做接口测试?

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 01、通用的项目架构 02、什么是接口 接口&#xff1a;服务端程序对外提供的一种统一的访问方式&#xff0c;通常采用HTTP协议&#xff0c;通过不同的url&#xff…

父文档检索器引和RAG的context precision性能指标

父文档检索器引和context precision性能指标 父文档检索器是一种搜索工具,用来从一大堆文档中找出跟你的问题最相关的答案。它的特别之处在于,它会先把文档分成小块(子片段),然后找到最相关的小块,再返回这些小块所属的完整大文档(父文档)。这样既能精准找到相关内容,…

平台化 LIMS 系统架构 跨行业协同与资源共享的实现路径

在科技快速发展的今天&#xff0c;质检行业正面临着效率、合规和数据安全的多重挑战。新一代质检 LIMS 系统以智能化与平台化为核心&#xff0c;为实验室管理提供了全新的解决方案。 一、智能化&#xff1a;从数据采集到分析的全流程升级 传统质检流程中&#xff0c;人工数据录…

[蓝桥杯]路径之谜

路径之谜 题目描述 小明冒充 XX 星球的骑士&#xff0c;进入了一个奇怪的城堡。 城堡里边什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡地面是 nnnn 个方格。如下图所示。 按习俗&#xff0c;骑士要从西北角走到东南角。可以横向或纵向移动&#xff0c;但不能斜…

奥威BI+AI数据分析:企业数智化转型的加速器

在当今数据驱动的时代&#xff0c;企业对于数据分析的需求日益增长。奥威BIAI数据分析的组合&#xff0c;正成为众多企业数智化转型的加速器。 奥威BI以其强大的数据处理和可视化能力著称。它能够轻松接入多种数据源&#xff0c;实现数据的快速整合与清洗。通过内置的ETL工具&…

大模型的外围关键技术

最简易前端&#xff1a;Gradio 基本介绍 Gradio 是一个用于快速创建可分享的机器学习模型界面的开源 Python 库。通过 Gradio&#xff0c;开发者能够轻松地为他们的模型创建前端界面&#xff0c;从而使非技术用户也可以通过简单的网页界面与这些模型进行交互。 Gradio 的一些…

electron定时任务,打印内存占用情况

// 监听更新 function winUpdate(){// 每次执行完后重新设置定时器try {// 获取当前时间并格式化为易读的字符串const now new Date();const timeString now.toLocaleString();console.log(当前时间: ${timeString});// 记录内存使用情况&#xff08;可选&#xff09;const m…

建筑工程施工进度智能编排系统 (SCS-BIM)

建筑工程施工进度智能编排 (SCS-BIM) 源码可见于&#xff1a;https://github.com/Asionm/SCS-BIM 项目简介 本项目是一个面向建筑工程的施工进度智能编制平台&#xff0c;用户只需上传一份标准 IFC 建筑信息模型文件&#xff0c;系统将自动完成以下任务&#xff1a; 解析模…

小红薯商品搜索详情分析与实现

前言 小红书作为国内知名的社交电商平台&#xff0c;拥有丰富的商品数据和用户评价信息。对于数据分析师、产品经理或电商从业者来说&#xff0c;能够获取小红书的商品数据具有重要的商业价值。本文将详细介绍如何通过逆向工程实现小红书商品搜索API的调用。 免责声明&#xf…

国标GB28181设备管理软件EasyGBS视频平台筑牢文物保护安全防线创新方案

一、方案背景​ 文物作为人类文明的珍贵载体&#xff0c;具有不可再生性。当前&#xff0c;盗窃破坏、游客不文明行为及自然侵蚀威胁文物安全&#xff0c;传统保护手段存在响应滞后、覆盖不全等局限。随着5G与信息技术发展&#xff0c;基于GB28181协议的EasyGBS视频云平台&…

使用 Python + ExecJS 获取网易云音乐歌曲歌词

&#x1f3b5; 使用 Python ExecJS 获取网易云音乐歌曲歌词 在本篇博客中&#xff0c;我们将通过一个完整的 Python 脚本&#xff0c;利用 execjs 模块调用 JavaScript 代码&#xff0c;成功获取网易云音乐的歌曲歌词。整个过程涵盖了加密参数的生成、API 请求发送与歌词提取…

云台式激光甲烷探测器:守护工业安全的“智慧之眼”

在石油化工、天然气场站、城市燃气管网等场景中&#xff0c;甲烷泄漏的早期监测是保障生产安全的核心防线。云台式激光甲烷探测器凭借高精度、无接触、智能化的技术优势&#xff0c;成为工业安全监测领域的革新者。本文将深度解析其技术原理、核心功能及适用场景&#xff0c;助…

基于YOLO-NAS-Pose的无人机象群姿态估计:群体行为分析的突破

【导读】 应对气候变化对非洲象的生存威胁&#xff0c;本研究创新采用无人机航拍结合AI姿态分析技术&#xff0c;突破传统观测局限。团队在肯尼亚桑布鲁保护区对比测试DeepLabCut与YOLO-NAS-Pose两种模型&#xff0c;首次将后者引入野生动物研究。通过检测象群头部、脊柱等关键…

CppCon 2014 学习:Anatomy of a Smart Pointer

智能指针&#xff08;smart pointer&#xff09;可以这样解释&#xff1a; 它是一个指针的容器——内部保存了一个普通指针&#xff0c;并且可以在需要时把指针交给你使用。它支持RAII&#xff08;资源获取即初始化&#xff09;&#xff0c;也就是说资源&#xff08;比如内存&…

GNhao,国外云手机号智能选择与应用解析!

GNhao&#xff0c;国外云手机号智能选择与应用解析&#xff01; 在数字时代&#xff0c;国外云手机号成为跨境沟通的关键。GNhao凭借其稳定的国外云手机号服务&#xff0c;满足了用户多样需求&#xff0c;提升了通讯效率。国外云手机号广泛应用于海外注册、跨境营销和社交&…