JSON Web Token(JWT)是一个非常轻巧的规范,这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。它是基于RFC 7519标准定义的一种可以安全传输的小巧和自包含的JSON对象。由于数据是使用数字签名的,所以是可信任的和安全的。JWT可以使用HMAC算法对secret进行加密或者使用RSA的公钥私钥对其进行签名。
{
"typ": "JWT",
"alg": "HS256"
}
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
{
"iss": "why",
"iat": 1416797419,
"exp": 1448333419,
"aud": "www.example.com",
"sub": "taobao.com",
}
ewogICJpc3MiOiAid2h5IiwgCiAgImlhdCI6IDE0MTY3OTc0MTksIAogICJleHAiOiAxNDQ4MzMzNDE5LCAKICAiYXVkIjogInd
3dy5leGFtcGxlLmNvbSIsIAogICJzdWIiOiAidGFvYmFvLmNvbSIsIAp9
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ewogICJpc3MiOiAid2h5IiwgCiAgImlhdCI6IDE0MTY3OTc0MTksIAogICJleHAiOiAxNDQ4MzMzNDE5LCAKICAiYXVkIjogInd
3dy5leGFtcGxlLmNvbSIsIAogICJzdWIiOiAidGFvYmFvLmNvbSIsIAp9
我们将上面拼接完的字符串用HS256算法进行加密,在加密的时候,提供一个密钥(secret),然后对上面的字符串进行加密后得到签名
6OcLdX38eKWn1gCyJ6RNwsAvIvXxYq1CGBkFWgiTsyc
最后,将将这一部分也用句号拼接在字符串后面,就形成了
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ewogICJpc3MiOiAid2h5IiwgCiAgImlhdCI6IDE0MTY3OTc0MTksIAogICJleHAiOiAxNDQ4MzMzNDE5LCAKICAiYXVkIjogInd
3dy5leGFtcGxlLmNvbSIsIAogICJzdWIiOiAidGFvYmFvLmNvbSIsIAp9.6OcLdX38eKWn1gCyJ6RNwsAvIvXxYq1CGBkFWgiTsyc
package why.test;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
/**
* @Author: 王洪玉
* @Decsription: 生成Token的工具类
* @Create: 2017/11/12 20:06
* @Modified By:
*/
public class TokenUtil {
private static final String APP_KEY = "why_key"; //进行数字签名的私钥,一定要保管好,不能和我一样写到博客中。。。。。
private TokenUtil(){
}
/**
* 一个JWT实际上就是一个字符串,它由三部分组成,头部(Header)、载荷(Payload)与签名(Signature)
* @param id 当前用户ID
* @param issuer 该JWT的签发者,是否使用是可选的
* @param subject 该JWT所面向的用户,是否使用是可选的
* @param ttlMillis 什么时候过期,这里是一个Unix时间戳,是否使用是可选的
* @param audience 接收该JWT的一方,是否使用是可选的
* @return
*/
public static String createJWT(String id,String issuer,String subject,long ttlMillis, String audience){
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(APP_KEY);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
JwtBuilder jwtBuilder = Jwts.builder()
.setId(id)
.setSubject(subject)
.setIssuedAt(now)
.setIssuer(issuer)
.setAudience(audience)
.signWith(signatureAlgorithm,signingKey);
//设置Token的过期时间
if(ttlMillis >=0){
long expMillis = nowMillis + ttlMillis;
Date exp = new Date(expMillis);
jwtBuilder.setExpiration(exp);
}
return jwtBuilder.compact();
}
//私钥解密token信息
public static Claims getClaims(String jwt) {
return Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(APP_KEY))
.parseClaimsJws(jwt).getBody();
}
}
@Test
public void testCreateToken(){
String userId = "WKSH121321KKsdfk";
String issuer = "http://whytfjybj.com";
String subject = "师范学院";
long ttlMillis = 1000 * 60;
String audience = "schoolNo";
String token = TokenUtil.createJWT(userId,issuer,subject,ttlMillis,audience);
//打印出token信息
System.out.println(token);
// 解密token信息
Claims claims = TokenUtil.getClaims(token);
System.out.println("---------------------------解密的token信息----------------------------------");
System.out.println("ID: " + claims.getId());
System.out.println("Subject: " + claims.getSubject());
System.out.println("Issuer: " + claims.getIssuer());
System.out.println("Expiration: " + claims.getExpiration());
}