当前位置: 首页 > news >正文

JWT的工作流程

第一部分:密码验证

密码验证的核心原则是:服务器绝对不能也无需存储用户的明文密码。存储明文密码是极其危险的,一旦数据库泄露,所有用户密码都将暴露。

标准流程(使用哈希加盐)
  1. 用户注册

    • 步骤1: 用户在客户端(如网页、App)输入用户名和密码(明文)。
    • 步骤2: 客户端将注册信息(包含明文密码)通过 HTTPS 安全地发送到服务器。
    • 步骤3: 服务器收到请求后,并不会直接存储密码。而是会进行以下操作:
      • 生成一个随机“盐”(Salt):一个长而随机的字符串,每个用户的盐都不同。
      • 将盐与明文密码组合:例如 salt + password
      • 使用哈希函数(如 bcrypt, scrypt, Argon2)进行加密:将组合后的字符串通过哈希函数计算,生成一个固定长度的、看起来毫无规律的“密码哈希值”。
      • 存储信息:将 用户名密码哈希值 一起存入数据库。
    用户名密码(数据库中存储的)
    alice$2b$10$N9qo8u...iuHS01N9qo8u...iuHS01 (通常和哈希值存在一起)
    bob$2b$10$s6B6f7...fG2sA2s6B6f7...fG2sA2

    为什么用 bcrypt 而不是 MD5/SHA-256?
    bcrypt 是专门为密码设计的哈希算法,它速度很慢(可以通过“工作因子”调整),并且内置了盐的处理,能有效抵御暴力破解和彩虹表攻击。而 MD5/SHA 速度太快,不适合用于密码哈希。

  2. 用户登录

    • 步骤1: 用户在客户端输入用户名和密码(明文)。
    • 步骤2: 客户端通过 HTTPS 将登录信息发送到服务器。
    • 步骤3: 服务器根据用户名从数据库中查找对应的记录。
      • 如果找不到用户,返回错误“用户名或密码错误”。
    • 步骤4: 服务器进行密码验证(这是最关键的一步):
      • 从数据库中找到该用户对应的
      • 将接收到的明文密码与这个 进行组合。
      • 使用相同的哈希函数(如 bcrypt)对组合后的字符串进行哈希计算。
      • 将计算出的新哈希值与数据库中存储的旧哈希值进行比对。
    • 步骤5: 如果两个哈希值完全一致,则证明密码正确;否则,密码错误。

核心思想:服务器不比较密码本身,而是比较用同样方法和盐计算出的哈希值。即使两个用户密码相同,因为他们的盐不同,最终存储的哈希值也完全不同。


第二部分:JWT (JSON Web Token) 流程

密码验证成功后,服务器需要一种方式来记住用户已经登录过了。传统的做法是用 Session/Cookie,而 JWT 是一种更现代、无状态的替代方案。

JWT 的本质是一个数字签名的令牌,它本身就包含了用户的身份信息(称为“声明”)。

JWT 的组成

一个 JWT 看起来像这样:xxxxx.yyyyy.zzzzz,它由三部分组成,用点号分隔:

  1. Header (头部)

    • 通常包含令牌类型(typ: "JWT")和所用的签名算法(alg: "HS256")。
    • 这是一个 Base64Url 编码的 JSON 字符串。
  2. Payload (有效载荷)

    • 包含你要发送的“声明”(用户信息和其他数据)。常见的声明有:
      • sub (Subject):用户ID
      • name:用户名
      • iat (Issued At):令牌签发时间
      • exp (Expiration Time):令牌过期时间
    • 注意:Payload 只是经过 Base64Url 编码,并没有加密**。任何人都可以解码看到内容。所以绝不能在里面存放敏感信息(如密码)
  3. Signature (签名)

    • 这是 JWT 的安全核心。签名用于验证消息在整个过程中没有被篡改。
    • 生成方式:签名 = HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
    • 服务器用一个只有自己知道的密钥(secret)来生成这个签名。如果头部或有效载荷被修改,没有密钥就无法生成匹配的新签名,验证就会失败。
      #### JWT 的工作流程(登录成功后)
  4. 签发 Token (登录成功时)

    • 在密码验证通过后,服务器端生成 JWT。
    • Payload 中会包含用户身份信息,如 { "sub": "12345", "name": "alice", "exp": 1735689600 }
    • 用 Header 里声明的算法和服务器自己的 secret 密钥生成签名。
    • 将三部分组合成一个字符串 JWT Token,返回给客户端(通常放在 HTTP 响应的 Body 或一个 Header 里)。
  5. 客户端存储和发送 Token

    • 客户端(通常是浏览器)收到 JWT 后,需要把它存储起来(常见做法是存在 localStoragesessionStorageCookie 中)。
    • 此后,客户端每次向服务器请求需要认证的 API(如获取个人资料),都必须在 HTTP 请求的 Authorization 头部带上这个 Token:
      Authorization: Bearer <你的JWT令牌>
  6. 验证 Token (访问受保护接口时)

    • 服务器收到请求后,从 Authorization 头中取出 JWT。
    • 验证签名:这是最关键的一步。服务器用自己的 secret 密钥,按照 Header 中指定的算法,对收到的 Header 和 Payload 部分重新计算一次签名。
    • 比对签名:将计算出的新签名与 JWT 自带的第三部分(Signature)进行比对。
      • 如果签名不一致:说明 Token 被篡改了,立即拒绝请求。
      • 如果签名一致:证明 Token 是有效且未被篡改的,服务器可以信任 Payload 中的信息。
    • (可选)检查其他声明:检查 Token 是否过期(exp)、是否提前生效(nbf)等。
    • 验证全部通过后,服务器就从 Payload 中的 sub (用户ID) 知道这个请求是谁发出的,然后处理业务逻辑并返回数据。
http://www.dtcms.com/a/389580.html

相关文章:

  • Java 25 新特性 更简洁、更高效、更现代
  • 探讨前端与后端的安全策略:保护用户数据的关键措施
  • 如何使用DeepSeek等AI工具来帮助自己的工作
  • 灵途科技亮相CIOE2025 | 光电感知赋能具身智能升级
  • 我的云端影院:LibreTV+cpolar的异地观影记
  • NW748NW765美光固态闪存NW775NW781
  • 软考中级习题与解答——第八章_计算机网络(1)
  • Playwright 完全指南:从入门到实战,解锁自动化测试新范式
  • OpenCV:直接用NV21/NV12格式,画线、贴图都是相加效果,而不是替换、覆盖
  • MCP3421与STM32电压采集实现
  • 表白网页制作免费网站制作 表白网站建设教程
  • 嵌入式Linux C语言程序设计一、二
  • cocos做简单自动发射追踪子弹 切换敌人
  • C#知识学习-014(修饰符_3)
  • Linux 下逆向解析 VNC Server 密码文件为明文密码(逆向解析passwd)
  • Linux dma_resv机制原理、实现与应用详解
  • LangGraph 进阶学习
  • Alibaba Cloud Linux与 RHEL/CentOS版本对应关系
  • Python实现PDF文本与表格转换
  • 医疗行业数字化转型:构建安全合规、高效协同的智慧医疗文档管理新范式
  • 怎么看一个网址是否安全?
  • 【LLM】RAG架构如何重塑大模型
  • 企业级数据库管理实战(四):从 C/S 到 B/S架构,数据库管理工具的演进
  • 基于AI的PDF复杂表格结构识别与智能解析(方案1)
  • CS336第三课
  • 云蝠智能大模型呼叫对话延迟无限接近1秒
  • Datax-web安装 | 配置环境
  • 算法<java>——查找(顺序、二分、插值、分块、斐波那契)
  • Mysql杂志(十九)——InnoDB的索引结构
  • CrowdStrike推出AI驱动新工具 聚焦补丁管理与威胁情报短板