jwtjava
A. 如何在java 中创建和验证JWT
用户发起登录请求,服务端创建一个加密后的jwt信息,作为token返回值,在后续请求中jwt信息作为请求头,服务端正确解密后可获取到存储的用户信息,表示验证通过;解密失败说明token无效或者已过期。
加密后jwt信息如下所示,是由.分割的三部分组成,分别为Header、Payload、Signature。
eyJhbGciOiJIUzI1NiJ9..vW-
Header包含两部分信息,alg指加密类型,可选值为HS256、RSA等等,typ=JWT为固定值,表示token的类型。
{
"alg": "HS256",
"typ": "JWT"
}
Payload是指签名信息以及内容,一般包括iss (发行者), exp (过期时间), sub(用户信息), aud (接收者),以及其他信息,详细介绍请参考官网。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Signature则为对Header、Payload的签名。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
在jwt官网,可以看到有不同语言的实现版本,这里使用的是Java版的jjwt。话不多说,直接看代码,加解密都很简单:
/**
* 创建 jwt
* @param id
* @param subject
* @param ttlMillis
* @return
* @throws Exception
*/
public String createJWT(String id, String subject, long ttlMillis) throws Exception {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256 ;
long nowMillis = System. currentTimeMillis();
Date now = new Date( nowMillis);
SecretKey key = generalKey();
JwtBuilder builder = Jwts. builder()
.setId(id)
.setIssuedAt(now)
.setSubject(subject)
.signWith(signatureAlgorithm, key);
if (ttlMillis >= 0){
long expMillis = nowMillis + ttlMillis;
Date exp = new Date( expMillis);
builder.setExpiration( exp);
}
return builder.compact();
}
/**
* 解密 jwt
* @param jwt
* @return
* @throws Exception
*/
public Claims parseJWT(String jwt) throws Exception{
SecretKey key = generalKey();
Claims claims = Jwts. parser()
.setSigningKey( key)
.parseClaimsJws( jwt).getBody();
return claims;
}
加解密的key是通过固定字符串转换而生成的;subject为用户信息的json字符串;ttlMillis是指token的有效期,时间较短,需要定时更新。
这里要介绍的token刷新方式,是在生成token的同时生成一个有效期较长的refreshToken,后续由客户端定时根据refreshToken来获取最新的token。浏览器与服务端之间建立sse(server send event)请求,来实现刷新。关于sse在前面博文中有介绍过,此处略过不提。
B. java jwt token 生成很慢啊
jwt不算慢,基本是毫秒,你测试的方法估计有问题,单元测试1次jwt生成基本都是1~2秒,因为java程序刚刚启动占用大量资源,你循环1000次jwt生成速度对比就知道了, 基本是毫秒级别!