Java中的JWT令牌:JSON Web Tokens完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java中的JWT令牌:创建、验证与使用



JSON Web Token (JWT) 是一种紧凑且自包含的方式,以JSON对象的形式在各方之间传输信息。在Java中,JWT广泛用于REST API和微服务架构中的认证、授权和数据交换。本文将介绍Java中最流行的两个JWT库——Stormpath的JJWT (Java JWT) 和Auth0的java-jwt,并探讨如何与Spring Security集成。



什么是JWT以及为什么需要它?



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

  • Header — 头部,包含令牌类型和签名算法(例如HS256或RS256)。
  • Payload — 有效载荷,包含声明(claims),如用户ID、角色、过期时间。
  • Signature — 签名,基于header、payload和密钥生成。


在Java中,JWT最常用于:

  • 无状态用户认证(无需在服务器保存会话)。
  • 在微服务之间传递访问权限。
  • 用于密码重置或邮箱确认的一次性令牌。


JJWT库 (io.jsonwebtoken)



JJWT 是Java中最流行的JWT库。它易于使用,支持所有标准算法(HS256、RS256、ES256),并且持续更新。



通过Maven引入JJWT

<dependency>    <groupId>io.jsonwebtoken</groupId>    <artifactId>jjwt-api</artifactId>    <version>0.12.6</version></dependency><dependency>    <groupId>io.jsonwebtoken</groupId>    <artifactId>jjwt-impl</artifactId>    <version>0.12.6</version>    <scope>runtime</scope></dependency><dependency>    <groupId>io.jsonwebtoken</groupId>    <artifactId>jjwt-jackson</artifactId>    <version>0.12.6</version>    <scope>runtime</scope></dependency>


创建JWT令牌

import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import io.jsonwebtoken.security.Keys;import javax.crypto.SecretKey;import java.util.Date;

public class JwtExample { public static void main(String[] args) { // 为HS256生成安全密钥 SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

String token = Jwts.builder() .subject("user123") .claim("role", "admin") .issuedAt(new Date()) .expiration(new Date(System.currentTimeMillis() + 3600000)) // 1小时 .signWith(key) .compact();

System.out.println("生成的JWT: " + token); }}


验证和解析JWT

import io.jsonwebtoken.Claims;import io.jsonwebtoken.Jws;import io.jsonwebtoken.JwtException;import io.jsonwebtoken.Jwts;

public class JwtParserExample { public static void main(String[] args) { String jwtToken = "eyJhbGciOiJIUzI1NiJ9..."; // 你的令牌 SecretKey key = ...; // 与创建时相同的密钥

try { Jws<Claims> claimsJws = Jwts.parser() .verifyWith(key) .build() .parseSignedClaims(jwtToken);

Claims claims = claimsJws.getPayload(); System.out.println("Subject: " + claims.getSubject()); System.out.println("Role: " + claims.get("role")); System.out.println("Expiration: " + claims.getExpiration()); } catch (JwtException e) { System.out.println("令牌无效: " + e.getMessage()); }

推荐