JSON WEB TOKEN - 告別session和cookie - java demo

JWT簡介

JWT認證流程:php

  1. 用戶登陸成功,生成token,返回一個對象(包含token,用戶名)
  2. 每次請求都帶上這個對象(經過js存儲在電腦)
  3. jwt過濾器會校驗token解密以後的name是否和用戶名相同,相同則放行
  4. 完成(後續可能須要加上token刷新的動做)

詳細介紹:JWT 丨 JSON Web Tokens 丨 java-jwt | 詳細介紹以及用法java

maven依賴

<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.2.0</version> </dependency>

JWT生成與解密

package com.hisen.jars.jwt;

import com.alibaba.fastjson.JSON; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.DecodedJWT; import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.joda.time.DateTime; /** * 利用java-jwt 3.2.0版本 * 每一個版本的方法不大同樣 * Created by hisenyuan on 2017/8/17 at 15:41. */ public class Jwt { private static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545df>?N<:{LWPW_hisen"; private static final String EXP = "exp"; private static final String PAYLOAD = "payload"; /** * 生成Token:jwt * @param object 傳入的加密對象 - 放入PAYLOAD * @param maxAge 過時事件,單位毫秒 * @param <T> * @return */ public static <T> String sign(T object, long maxAge) { Map<String, Object> map = new HashMap<String, Object>(); String jsonString = JSON.toJSONString(object); map.put("alg", "HS256"); map.put("typ", "JWT"); long exp = System.currentTimeMillis() + maxAge; System.out.println("JWTUtil 當前時間:"+new DateTime().toString("yyyy-MM-dd HH:mm:ss EE")); System.out.println("JWTUtil 過時時間:"+new DateTime(exp).toString("yyyy-MM-dd HH:mm:ss EE")); String token = null; try { token = JWT.create() .withHeader(map)//header .withClaim(PAYLOAD, jsonString)//存放的內容 json .withClaim(EXP, new DateTime(exp).toDate())//超時時間 .sign(Algorithm.HMAC256(SECRET));//密鑰 } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return token; } /** * 解密token * @param token jwt類型的token * @param classT 加密時的類型 * @param <T> * @return 返回解密後的對象 - 若是token過時返回空對象 */ public static <T> T unsign(String token, Class<T> classT) { DecodedJWT decode = JWT.decode(token); Map<String, Claim> claims = decode.getClaims(); if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)){ long tokenTime = claims.get(EXP).asDate().getTime(); long nowTime = new Date().getTime(); // 判斷令牌是否超時 if (tokenTime > nowTime){ String json = claims.get(PAYLOAD).asString(); return JSON.parseObject(json, classT); } } return null; } }

解密的另一種寫法

這種寫法若是令牌超時,直接運行時異常,沒法作相關處理django

/** * 解密token * @param token jwt類型的token * @param classT 加密時的類型 * @param <T> * @return 返回解密後的對象 - 若是token過時返回空對象 */ public static <T> T unsign(String token, Class<T> classT) { JWTVerifier verifier = null; try { verifier = JWT.require(Algorithm.HMAC256(SECRET)).build(); DecodedJWT jwt = verifier.verify(token); // 若是超時,直接拋出運行時異常 Map<String, Claim> claims = jwt.getClaims(); if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) { long tokenTime = claims.get(EXP).asDate().getTime(); long now = new Date().getTime(); // 判斷令牌是否已經超時 if (tokenTime > now) { String json = claims.get(PAYLOAD).asString(); // 把json轉回對象,返回 return JSON.parseObject(json, classT); } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (TokenExpiredException e){ e.printStackTrace(); } return null; }
相關文章
相關標籤/搜索