详细分析JWT的基本知识(附Demo)

前言

对于Java的基本知识推荐阅读:

  1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
  2. 【Java项目】实战CRUD的功能整理(持续更新)

1. 基本知识

紧凑的、URL-safe 的表示方式,通常用于认证和信息交换

JWT 由三部分组成,用点号分隔:

  • Header(头部):通常包括令牌的类型(JWT)和所使用的签名算法(如 HMAC SHA256 或 RSA)
  • Payload(负载):包含要传递的声明(Claims),例如用户信息、权限等
  • Signature(签名):使用头部中指定的算法对编码后的头部和负载进行签名,以确保信息的完整性和来源的真实性

为了更好的解析jwt的组成,我们找一个网址,查看本地存储所得到的jwt,去解析:https://jwt.io/

截图如下:(为避免不必要,已将多数数据隐藏)

在这里插入图片描述

一、Header(头部)

  • 类型(typ):通常为 JWT,表示这是一个 JSON Web Token
  • 算法(alg):指定用于签名的算法

例如,HS256 代表 HMAC SHA-256 算法
头部被 Base64 URL 编码后,通常如下所示:

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

二、Payload(负载)

  • 注册声明(Registered Claims):这些是预定义的声明,如 exp(过期时间)、iss(发行者)、sub(主题)等
  • 公共声明(Public Claims):自定义声明,可以与 IANA 注册表中的标准声明名称进行匹配
  • 私有声明(Private Claims):应用程序之间自定义的声明,用于传递特定的信息

jti:唯一的令牌标识符,用于防止重放攻击

三、 Signature(签名)

签名部分用于验证消息的完整性和来源,通过对编码后的头部和负载进行 HMAC SHA-256 签名生成的

公式如下:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret
)

验证JWT是否被修改的过程:

  1. 解码 Header 和 Payload
    将 Base64 URL 编码后的 Header 和 Payload 部分进行解码

  2. 验证 Signature
    使用密钥(your-256-bit-secret)和指定的算法(HS256)对 Header 和 Payload 进行签名,生成一个签名部分
    验证生成的签名与 JWT 的实际签名部分是否一致,以确定令牌是否被篡改

总的来说JWT 的各部分作用:

部分描述作用
Header包含令牌的元数据,如类型和算法指定令牌类型和签名算法
Payload包含声明信息,包括注册声明、公共声明和私有声明传递用户和权限信息等
Signature使用头部中指定的算法和密钥对 Header 和 Payload 进行签名验证令牌的完整性和来源

JWT 与其他认证机制对比

特性/机制JWTSession-Based AuthenticationOAuth2API Key
认证类型无状态(Stateless)有状态(Stateful)无状态(Stateless)无状态(Stateless)
存储位置客户端存储(通常在本地存储或 Cookie 中)服务器端存储会话信息通常使用访问令牌存储在客户端或服务器端客户端存储(通常在请求头中)
扩展性适合分布式系统和微服务架构不适合扩展到分布式系统或微服务支持授权和资源访问控制,适合大型应用适合简单的 API 访问控制
安全性签名保证数据完整性,但需要 HTTPS 保护服务器端存储提供安全性,但会话劫持问题OAuth2 提供了多层安全性(如授权码流、客户端流等)安全性较低,容易被暴露
易用性易于在客户端和服务器端使用,支持多种语言和平台服务器需要管理会话,较复杂需要处理授权过程,较复杂简单直接,但不支持细粒度的权限控制
过期管理内置过期时间,通常在令牌中指定需要服务器端管理会话过期通过刷新令牌机制管理需要手动管理过期和权限
适用场景适合 API 身份验证、微服务架构适合传统的 web 应用适合第三方应用授权、复杂的用户权限控制适合简单的服务或接口调用

2. JWT验证过程

在客户端和服务器之间安全地传递信息的机制,在身份验证过程中,JWT 用于证明用户的身份,并在服务器上进行授权

精简的步骤如下:

一、用户登录
1.1 用户提供凭据(如用户名和密码)到服务器
1.2 服务器验证凭据,生成 JWT 如果凭据有效,服务器生成一个 JWT。该令牌通常包含用户的身份信息(如用户ID、角色等)以及其他声明(如过期时间 exp)
1.3 服务器返回 JWT 给客户端

二、客户端使用 JWT
客户端将 JWT 存储在本地(如 localStorage)
客户端在请求受保护资源时,将 JWT 附加到请求的 Authorization 头中

三、服务器验证 JWT
服务器接收请求,提取并解码 JWT。(服务器从请求的 Authorization 头中提取 JWT,并对其进行 Base64 解码以获取 Header 和 Payload 部分)
验证 JWT 签名和有效性(如过期时间)。(服务器使用预先定义的密钥和算法(如 HMAC SHA-256)对 JWT 的签名进行验证,以确保令牌没有被篡改)
如果有效,授权访问资源;否则,返回 401 错误

四、处理请求
服务器根据 JWT 中的信息处理请求并返回数据
客户端处理服务器响应

基本的交互形式如下:

登录请求

客户端请求:

POST /login HTTP/1.1
Host: example.com
Content-Type: application/json

{
  "username": "john",
  "password": "password123"
}

服务器响应:

{
  "access_token": "eyJhbGciOiAiSFMyNTYiLCAiaWF0IjogMTYzNjIxxxxx.eyJzdWIiOiIxMjM0NTY3ODkwIiwgIm5hbWUiOiJKb2huIERvZSIsICJpYXQiOiAxNjM2MjQ3ODYxLCAiZXhwIjogMTYzNjI1MxxxxxxHRJ7to7Yb2PTthg4civ9kW-FwcE"
}

访问受保护资源

客户端请求:

GET /protected-resource HTTP/1.1
Host: example.com
Authorization: Bearer eyJhbGciOiAiSFMyNTYiLCAiaWF0IjogMTYzNjI0Nzg2MSxxxxxx6IDE2MzYyNTExNjF9.eyJzdWIiOiIxMjM0NTY3ODkwIiwgIm5hbWUiOiJKb2huIERvZSIsICJpYXQiOiAxNjM2MjQ3ODYxLCxxxxxxjI1MTE2MX0._XxZ9mOeA9v0qjPvHRJ7to7Yb2PTthg4civ9kW-FwcE

服务器响应:

{
  "data": "This is a protected resource."
}

3. Demo

使用 Node.js 和 jsonwebtoken 库的简单示例,演示如何生成和验证 JWT:

const jwt = require('jsonwebtoken');

// 密钥,用于签名和验证 JWT
const secretKey = 'your-very-secure-secret';

// 生成 JWT
function generateToken(payload) {
    return jwt.sign(payload, secretKey, { expiresIn: '1h' });
}

// 验证 JWT
function verifyToken(token) {
    try {
        const decoded = jwt.verify(token, secretKey);
        return { valid: true, decoded };
    } catch (error) {
        return { valid: false, error: error.message };
    }
}

// 示例使用
const payload = { userId: 123, role: 'admin' };
const token = generateToken(payload);
console.log('Generated JWT:', token);

const verificationResult = verifyToken(token);
console.log('Verification Result:', verificationResult);
  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值