了解 JWT 和 Java-JWT 在 Web 应用中的应用和实现

1. 什么是JWT?

JWT全称为Json Web Token,是一种用于身份验证和授权的开放标准。它将一些声明(例如用户身份信息)作为JSON对象进行传输,使用数字签名或加密确保数据的安全性。

2. JWT的基本结构

一个JWT主要由头部(Header)、载荷(Payload)和签名(Signature)三部分构成,它们使用Base64字符串进行编码。

  • 头部(Header):包含描述 JWT 的元数据,例如指定使用的算法(如HMAC SHA256或RSA)。
  • 载荷(Payload):存储有关用户的信息,以及其他自定义的声明。
  • 签名(Signature):使用私钥(或密钥)对头部和载荷进行加密生成的签名,用于验证数据的完整性和真实性。

2.1 头部(Header)

头部通常由两部分组成:令牌类型(typ)和签名算法(alg)。令牌类型通常是"JWT",而签名算法可以是HMAC、RSA或者其他加密算法。

示例:

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

2.2 载荷(Payload)

载荷是JWT的主要信息存储部分,通常包含一些声明(claims)和一些自定义的数据。声明分为三种类型:注册声明、公共声明和私有声明。

注册声明包括iss(签发者)、sub(面向的用户)、aud(接收方)、exp(过期时间)、iat(签发时间)和nbf(生效时间)等。

公共声明包括可以自定义的一些属性,但建议避免冲突。

私有声明包括自定义的一些属性,用于满足应用程序的需求。

示例:

{
  "sub": "1234567890",
  "name": "小王",
  "admin": true
}

2.3 签名(Signature)

签名部分使用Base64编码的头部和载荷,加上一个密钥(secret)通过指定的算法计算出来。通过对头部、载荷和密钥进行加密,可以验证数据在传输过程中是否被篡改。

示例:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

2.4 JWT 的工作原理

JWT 的工作原理如下:

  1. 客户端使用私钥和头部和载荷生成签名,并将头部、载荷和签名组合成一个字符串形式的 JWT。
  2. 客户端将 JWT 发送给服务器。
  3. 服务器使用存储的公钥对接收到的 JWT 进行验证和解析。
  4. 如果验证成功,服务器可以信任 JWT 中的信息,并根据需要执行相应的操作。

那么它在web应用里的工作流程如下:

JWT 和 Java-JWT 的工作流程

2.5 JWT 的优势和应用场景

JWT 具有以下优势和适用场景:

  • 简洁:JWT 使用 JSON 格式表示信息,具有可读性和简洁性。
  • 安全:通过签名验证和密钥加密,确保 JWT 的完整性和机密性。
  • 可扩展:JWT 的载荷支持自定义声明,可根据需求存储丰富的信息。
  • 无状态:服务器不需要在每次请求中保存会话信息,提高系统的可伸缩性。

JWT 在身份验证、单点登录、API 授权等场景中得到广泛应用。

3. Java-JWT简介

Java-JWT是一个用于生成和解析JWT的Java库,提供了简单易用的API和一些常用的功能。

3.1 添加依赖

你可以通过 Maven 或直接下载 jar 包的方式引入 Java-JWT。

Maven:

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.2</version>
</dependency>

Gradle:

implementation 'com.auth0:java-jwt:3.18.2'

3.2 生成JWT

下面是一个使用Java-JWT生成JWT的示例代码:

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;

// 生成JWT
String secret = "your-secret";
Algorithm algorithm = Algorithm.HMAC256(secret);

String token = JWT.create()
    .withIssuer("your-issuer")
    .withSubject("your-subject")
    .withAudience("your-audience")
    .withExpiresAt(new Date(System.currentTimeMillis() + 3600000))
    .withIssuedAt(new Date())
    .sign(algorithm);

System.out.println(token);

输出结果:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ5b3VyLWlzc3VlciIsInN1YiI6InlvdXItc3ViamVjdCIsImF1ZCI6InlvdXItYXVkaWVuY2UiLCJleHAiOjE2MzU1MzEzNzUsImlhdCI6MTYzNTUyNTc3NX0.7DkLDaiwD8q9dNzA7zY9EDcH2hQ8iZTnFyF4YIgohoA

3.3 解析JWT

下面是一个使用Java-JWT解析JWT的示例代码:

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;

// 解析JWT
String token = "your-token";
String secret = "your-secret";
Algorithm algorithm = Algorithm.HMAC256(secret);

try {
    JWTVerifier verifier = JWT.require(algorithm)
        .withIssuer("your-issuer")
        .withSubject("your-subject")
        .withAudience("your-audience")
        .build();

    DecodedJWT jwt = verifier.verify(token);
    System.out.println("Token verified");
    System.out.println("Subject: " + jwt.getSubject());
    System.out.println("Issued At: " + jwt.getIssuedAt());
    System.out.println("Expires At: " + jwt.getExpiresAt());
} catch (JWTVerificationException e) {
    System.out.println("Token verification failed");
    e.printStackTrace();
}

输出结果:

Token verified
Subject: your-subject
Issued At: Mon Sep 04 11:41:29 CST 2023
Expires At: Mon Sep 04 11:41:29 CST 2023

4. 总结

本文介绍了JWT的基本概念和结构,并展示了使用Java-JWT生成和解析JWT的示例代码。通过使用JWT,我们可以实现简单且安全的身份验证和授权机制。

正文到此结束
评论插件初始化中...
Loading...