前言
這裏不具體講解JWT是什麼,有什麼應用場景,只是一個簡單的小Demo,可以直接複製到eclipse上直接運行的,後續文章中再來詳細介紹下JWT的優勢和應用場景以及在單點登錄上的應用。
導入jar包
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
具體測試代碼
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
* @ClassName: JwtUtil
* @Description: JWT小Demo
* @author aiqinhai
* @date 2018年4月26日
*/
public class JwtUtil {
/**
* 創建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;
//生成JWT的時間
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
Map<String,Object> claims = new HashMap<String,Object>();
claims.put("uid", "uniqueID");
claims.put("user_name", "admin");
claims.put("nick_name","jiangmofeng");
SecretKey key = generalKey();
//爲payload添加各種標準聲明和私有聲明瞭
JwtBuilder builder = Jwts.builder()
//如果有私有聲明,一定要先設置這個自己創建的私有的聲明,這個是給builder的claim賦值
//一旦寫在標準的聲明賦值之後,就是覆蓋了那些標準的聲明的
.setClaims(claims)
//設置jti(JWT ID):是JWT的唯一標識,從而回避重放攻擊。
.setId(id)
.setIssuedAt(now)
//sub代表這個JWT的主體,即它的所有人。
.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() //得到DefaultJwtParser
.setSigningKey(key) //設置簽名的祕鑰
.parseClaimsJws(jwt).getBody();//設置需要解析的jwt
return claims;
}
/**
* 由字符串生成加密key
* @return
*/
public SecretKey generalKey(){
String stringKey = "aiqinhai";
byte[] encodedKey = Base64.decodeBase64(stringKey);//本地的密碼解碼[B@152f6e2
// 根據給定的字節數組使用AES加密算法構造一個密鑰
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
public static void main(String[] args){
JwtUtil util= new JwtUtil();
String ab=null;
try {
ab = util.createJWT("jwt", "{id:100,name:aiqinhai}", 600000);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("簽名之後的JWT:"+ab);
String jwt=ab;
Claims c=null;
try {
c = util.parseJWT(jwt);
//注意:如果jwt已經過期了,這裏會拋出jwt過期異常。
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(c.getId());
System.out.println(c.getIssuedAt());
System.out.println(c.getSubject());
System.out.println("獲取私有聲明中的nick_name:"+c.get("nick_name"));
System.out.println("獲取私有聲明中的user_name:"+c.get("user_name"));
System.out.println(c.get("uid", String.class));
}
}