JAVA实现JWT
Posted l_learning
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA实现JWT相关的知识,希望对你有一定的参考价值。
JWT介绍
详情访问官网https://jwt.io/
JWT是什么
JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息。此信息可以验证和信任,因为它是经过数字签名的。JWT可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对进行签名。
虽然 JWT 可以被加密以在各方之间提供保密性,但我们将重点关注签名令牌。签名令牌可以验证其中包含的声明的完整性,而加密令牌会对其他方隐藏这些声明。当使用公钥/私钥对令牌进行签名时,签名还证明只有持有私钥的一方才是签名方。
JWT使用场景
授权:JWT 最常见的场景。用户登录后,每个后续请求都将包括 JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是目前广泛使用 JWT 的一种功能,因为它的开销很小,并且能够轻松地跨不同的域使用。
信息交换:JWT 是在各方之间安全传输信息的好方法。因为 JWT 可以签名,例如,使用公钥/私钥对,您可以确保发送者是他们所说的人。此外,由于签名是使用报头和有效载荷计算的,因此您还可以验证内容没有被篡改。
JWT结构
JWT由三部分组成,由点(.)分隔,它们是:
- Header
- Payload
- Signature
因此,JWT通常如下所示。
xxxxx.yyyyy.zzzzz
Header
header 通常包含两部分:令牌类型(JWT)和使用的签名算法(如 HMAC SHA256 或 RSA)。
例如:
"alg": "HS256",
"typ": "JWT"
然后,对这个 JSON 进行 Base64Url 编码,形成 JWT 的第一部分。
Payload
token 的第二部分是 payload,其中包含声明。声明是关于实体(通常是 User)和其他数据的声明。声明有三种类型:registered, public, and private claims。
“sub”: “1234567890”,
“name”: “John Doe”,
“admin”: true
Signature
要创建签名部分,您必须获取 header 的编码、payload 的编码、secret、
在header 指定算法,并对其进行签名。
例如,如果要使用 HMAC SHA256 算法,则将按以下方式创建签名:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
签名用于验证消息在发送过程中没有发生更改,如果是使用私钥签名的令牌,它还可以验证 JWT 的发送者是它所说的人。
Putting all together
输出是三个由点分隔的 Base64 URL 字符串,可以在 html 和 HTTP 环境中轻松传递,同时与基于 XML 的标准(如 SAML)相比更加紧凑。
下面显示了一个JWT,它对前一个 header 和 payload 编码,并用一个 secret 进行了签名。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JAVA JWT
这里使用JWT官方推荐的库 com.auth0 / java-jwt / 3.x.x 简单实现JWT
jdk:1.8 及以上
详情访问官方网址https://github.com/auth0/java-jwt
Maven
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.19.1</version>
</dependency>
JwtOperator 操作类
实现生成token,验证token,获取payload信息
public class JwtOperator
//密钥
private String secretKey = "firefly";
//过期时间
private Long expirationTimeInSecond = 1000L * 60 * 30;
//header
private Map<String, Object> headerClaims = new HashMap<>();
//payload
private Map<String, Object> payloadClaims = new HashMap<>();
private static final JwtOperator jwtOperator = new JwtOperator();
private JwtOperator()
public static JwtOperator getInstance()
return jwtOperator;
public JwtOperator withSecretKey(String secretKey)
this.secretKey = secretKey;
return this;
public JwtOperator withTimeOut(Long expirationTimeInSecond)
this.expirationTimeInSecond = expirationTimeInSecond;
return this;
public JwtOperator withHeader(Map<String, Object> headerClaims)
this.headerClaims = headerClaims;
return this;
public JwtOperator withPayload(Map<String, Object> payloadClaims)
this.payloadClaims = payloadClaims;
return this;
/**
* 创建token
* @return
*/
public String createToken()
Algorithm algorithm = Algorithm.HMAC256(secretKey);
String token = JWT.create()
.withExpiresAt(new Date(System.currentTimeMillis() + expirationTimeInSecond))
//Header
.withHeader(headerClaims)
//Payload
.withPayload(payloadClaims)
//Signature
.sign(algorithm);
return token;
/**
* 校验token
* @param token
* @return
*/
public Boolean verifyToken(String token)
try
getDecodedJWT(token);
catch (JWTVerificationException exception)
return false;
return true;
/**
* 获取 Header Claims
* @param token
* @param claimName
* @return
*/
public Claim getHeaderClaims(String token, String claimName)
DecodedJWT jwt = getDecodedJWT(token);
return jwt.getHeaderClaim(claimName);
/**
* 获取 Payload Claims
* @param token
* @return
*/
public Map<String, Claim> getPayload(String token)
DecodedJWT jwt = getDecodedJWT(token);
Map<String, Claim> claims = jwt.getClaims();
return claims;
/**
* 获取 Payload Claims
* @param token
* @param claimsName
* @return
*/
public Claim getPayloadClaims(String token, String claimsName)
DecodedJWT jwt = getDecodedJWT(token);
Claim claim = jwt.getClaim(claimsName);
return claim;
/**
* 解码
* @param token
* @return
*/
private DecodedJWT getDecodedJWT(String token)
Algorithm algorithm = Algorithm.HMAC256(secretKey);
JWTVerifier verifier = JWT.require(algorithm)
.build();
return verifier.verify(token);
测试JwtOperator
public class JwtOperatorTest
public static void main(String[] args) throws InterruptedException
Map<String, Object> header = new HashMap<>();
header.put("h1", "h1 value");
header.put("h2", "h2 value");
Map<String, Object> payload = new HashMap<>();
payload.put("p1", "p1 value");
payload.put("p2", "p2 value");
Map<String, Object> body = new HashMap<>();
body.put("username", "zhangsan");
body.put("age", 18);
payload.put("user", body);
String token = JwtOperator.getInstance()
.withHeader(header)
.withSecretKey("test")
.withTimeOut(1000L)
.withPayload(payload)
.createToken();
System.out.println(token);
Boolean isLogined = JwtOperator.getInstance().verifyToken(token);
System.out.println(isLogined);
System.out.println("payload: "+ JwtOperator.getInstance().getPayload(token));
System.out.println("payload-user: "+ JwtOperator.getInstance().getPayloadClaims(token, "user"));
打印结果
eyJoMSI6ImgxIHZhbHVlIiwiaDIiOiJoMiB2YWx1ZSIsInR5cCI6IkpXVCIsImFsZyI6IkhTMjU2In0.eyJwMSI6InAxIHZhbHVlIiwicDIiOiJwMiB2YWx1ZSIsImV4cCI6MTY1MDc5MTEyMywidXNlciI6eyJhZ2UiOjE4LCJ1c2VybmFtZSI6InpoYW5nc2FuIn19.03lYpMjJYFQ3am532iPiYm222Y-WPMrVvQCYinImBOE
true
payload: p1="p1 value", p2="p2 value", exp=1650791123, user="age":18,"username":"zhangsan"
payload-user: "age":18,"username":"zhangsan"
以上是关于JAVA实现JWT的主要内容,如果未能解决你的问题,请参考以下文章
Java实现Token登录验证(基于JWT的token认证实现)