JWT 是目前前后端分离、微服务架构中最常用的无状态身份认证方案。本文用简洁易懂的方式,带你快速掌握 JWT 的签发、传递与校验核心逻辑,轻松理解其工作原理与安全机制。

一、什么是JWT?

JWT(JSON Web Token)是一种轻量级的令牌格式标准(对应标准规范 RFC 7519)。它本质是一段加密的 JSON 字符串,包含了用户身份信息和校验信息,可在客户端和服务端之间安全传递,实现“无状态鉴权”,无需存储在服务器数据库中(无状态),验证时仅需验证签名合法性即可。

二、JWT的结构解析

一个完整的 JWT 令牌由 3 部分组成,用 . 连接,格式为:

Header.Payload.Signature

1. Header(头部)

头部主要包含两个信息:令牌类型(typ)和加密算法(alg),默认使用HS256(HMAC SHA256)算法。

示例(Base64编码前):

{
  "typ": "JWT",
  "alg": "HS256"
}

头部会经过 Base64编码(可逆),成为JWT的第一部分。

2. Payload(载荷)

载荷是 JWT 的核心载体,用于存储需要传递的用户信息(如用户ID、用户名、角色)和一些标准声明(可选)。

声明分三类:

  1. 注册声明(Registered Claims)
    1. iss (Issuer):签发者
    2. sub (Subject):主题(用户 ID)
    3. aud (Audience):受众
    4. exp (Expiration Time):过期时间
    5. nbf (Not Before):生效时间
    6. iat (Issued At):签发时间
    7. jti (JWT ID):唯一 ID(防重放)
  2. 公共声明(Public Claims)
    • 自定义字段,需在 IANA 注册表 注册或用 URI 命名防冲突
  3. 私有声明(Private Claims)
    • 双方约定的自定义字段,不公开

示例(Base64编码前):

{
  "sub": "123456",
  "username": "admin",
  "role": "superadmin",
  "exp": 1717248000,
  "iat": 1714656000
}

⚠️ 注意:Payload 部分的 Base64 编码是可逆的,不能存储敏感信息(如密码、手机号等),仅适合存储非敏感的用户标识信息。

3. Signature(签名)

签名是 JWT 实现防篡改的核心,其核心作用有两个:

  1. 验证令牌在传输过程中是否被非法篡改;
  2. 确认令牌确实由合法的服务端签发,避免恶意伪造的令牌通过认证;

签名的生成严格遵循固定逻辑,完全依赖 Header 中指定的加密算法,以最常用的 HS256(即 HMAC SHA256)算法为例,签名生成公式示意如下:

HMACSHA256(
  base64UrlEncode(Header) + "." +
  base64UrlEncode(Payload),
  secret  // 服务端独有密钥,不可泄露给客户端
)
  1. 对 JWT 的 Header、Payload 部分进行 Base64Url 编码(注意:是 Base64Url 编码,而非标准 Base64,可避免 URL 中的特殊字符冲突);
  2. 将编码后的 Header 和 Payload 用英文句号 . 连接,形成字符串 base64UrlEncode(Header) + "." + base64UrlEncode(Payload)
  3. 使用 Header 中指定的加密算法,结合密钥(secret),对上述拼接后的字符串进行加密,最终生成的加密结果即为 Signature(签名)。

⚠️ 注意:服务端的密钥(secret)是签名生成和验证的核心,必须严格保密,严禁泄露给客户端(如前端页面、APP 客户端)。一旦密钥泄露,攻击者可伪造任意 Header 和 Payload,并生成合法签名,从而绕过身份认证,造成安全风险。

三、JWT 完整工作流程

JWT的工作流程非常简洁,核心分为“登录签发令牌”和“后续请求验证令牌”两个阶段,全程无状态,无需服务端存储额外信息。

阶段1:登录认证,签发JWT令牌

用户首次登录时,服务端完成身份校验并生成 JWT 令牌,具体步骤如下:

  1. 用户在客户端(网页、APP等)输入用户名和密码,发起登录请求;
  2. 服务端接收请求后,对用户名和密码的合法性进行校验(如查询数据库进行比对);
  3. 校验通过后,服务端根据用户信息(如用户ID、角色权限等非敏感数据)生成 JWT 的Header(头部)和 Payload(载荷),再结合服务端密钥,生成 Signature(签名),最终拼接成完整的JWT令牌;
  4. 服务端将生成的 JWT 令牌返回给客户端。

阶段2:后续请求,验证JWT令牌

用户登录成功后,后续发起所有业务接口请求时,均需携带 JWT 令牌完成身份验证。

验证原理:JWT 的 Signature(签名)具有不可逆特性,服务端在验证时,会使用与签发时完全相同的加密算法和密钥,重新计算签名,并与令牌中原签名比对:

  • 若一致,说明 Header 和 Payload 未被篡改;
  • 若不一致,则表明数据被篡改,令牌无效。

具体验证步骤如下:

在这里插入图片描述

  1. 客户端收到 JWT 令牌后进行本地存储(如 localStorageCookiepinia);

  2. 客户端后续发起业务接口请求时,需在请求头中携带 JWT 令牌,标准格式如下:

    Authorization: Bearer <token>
    
  3. 服务端接收请求后,从请求头中提取 JWT 令牌;

  4. 服务端按英文句号 . 将令牌拆分为Header、Payload、Signature三部分;

  5. 服务端使用相同的密钥和加密算法,对编码后的Header、Payload重新生成签名;

  6. 对比重新生成的签名与原令牌的Signature:

    1. 若签名不一致:说明令牌被篡改,拒绝请求;
    2. 若签名一致:继续校验 Payload 中的 exp(过期时间),未过期则验证通过。
  7. 验证通过后,服务端从 Payload 中解析出用户信息(如用户ID),执行后续业务逻辑,返回请求结果。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐