1. 程式人生 > >JWT生成以及校驗(2017-12-26修改版)

JWT生成以及校驗(2017-12-26修改版)

不說了,直接貼程式碼

package com.life.app.token;

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.lang3.StringUtils;
import org.bouncycastle.util.encoders.Base64;

import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;


/**
 * Json web token 簽發
 *
 */
public class JWT {

	// 金鑰key
	private static final String SECRET_KEY = "xxxxxxx";
	
	/**
	 * 構造金鑰
	 * 
	 * @return
	 */
	private static SecretKey generalKey() {
		byte[] encodeKey = Base64.decode(SECRET_KEY);
		return new SecretKeySpec(encodeKey, 0, encodeKey.length, "AES");
	}
	
	/**
	 * 簽發JWT
	 * 
	 * @param jti JWT的唯一身份標識,主要用來作為一次性token(允許為空)
	 * @param sub JWT所面向的使用者(允許為空)
	 * @param expiredTimeAt 過期時間(當前時間ms+要過期時間ms),單位ms(允許為空)
	 * @param claims 荷載資訊
	 * @return
	 */
	public static String createJWT(String jti, String sub, long expiredTimeAt, Map<String, Object> claims) {
		// 獲取金鑰
		SecretKey secretKey = generalKey();
		// 構建JWT,並設定簽發時間,簽名演算法
		JwtBuilder builder = Jwts.builder()
				.setIssuedAt(new Date())
				.signWith(SignatureAlgorithm.HS256, secretKey);
		// 校驗jti
		if(!StringUtils.isBlank(jti)) {
			builder.setId(jti);
		}
		// 校驗sub
		if(!StringUtils.isBlank(sub)) {
			builder.setSubject(sub);
		}
		// 過期時間
		if (expiredTimeAt > 0) {
			Date expDate = new Date(expiredTimeAt);
			builder.setExpiration(expDate);
		}
		// 校驗
		if (claims != null) {
			// 儲存相關資訊
			for (Map.Entry<String, Object> en : claims.entrySet()) {
				builder.claim(en.getKey(), en.getValue());
			}
		}
		return builder.compact();
	}
	
	/**
	 * 
	 * 解析JWT字串
	 * 
	 * @param jwt
	 * @return claims,包括公告宣告,自定義宣告
	 * @throws ExpiredJwtException,SignatureException,Exception token已過期,簽名校驗失敗,其它錯誤
	 */
	public static Map<String, Object> parseJWT(String jwt) {
		SecretKey secretKey = generalKey();
		try {
			Map<String, Object> claims = Jwts.parser()
					.setSigningKey(secretKey)
					.parseClaimsJws(jwt)
					.getBody();
			return claims;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static void main(String[] args) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userId", 10000);
		String jwt = createJWT("", "", System.currentTimeMillis() + 30*60*1000, map);
		System.out.println(jwt);
		
		/**
		 * 之前parseJWT(jwt)返回的是Claims物件,
		 * Claims實現了Map介面,事實上就是對Map進行的封裝,所以可以直接返回Map
		 */
		Map<String, Object> claims = parseJWT(jwt);
		System.out.println(claims.get("userId"));
		System.out.println(claims.get("iat"));
		System.out.println(claims.get("exp"));
	}

}