jwt 0.9.0(三)jwt客戶端存儲狀態可行性分析,及Java代碼案例

Jwt客戶端存儲狀態可行性分析前端

一、前端首次訪問後臺,後臺生成token,放在http header的Authorization裏(官網推薦,可解決跨域cookie跨域問題),而且Authorization Type類型爲Bearer,將token返回給前端。java

二、後臺生成token的過程,包括給token指定加密協議好比HS56,加密類型好比「JWT」,自定義數據好比uuid,還有最重要的是記得指定一個超級複雜的密鑰,而且按期更換它,密鑰用於jwt簽名部分。還須要給jwt token指定一個合理的過時時間,這個也一樣很是重要。web

三、前端獲取token後存儲token,建議存入本地cookie。spring

四、前端再次發起後臺API接口訪問,此時須要帶上token,也是放在http header中且Authorization Type類型爲Bearer,後臺需校驗token的正確性後纔可訪問權限受限的API接口或其餘資源。apache

先添加maven依賴json

<dependency>
       <groupId>io.jsonwebtoken</groupId>
       <artifactId>jjwt</artifactId>
       <version>0.9.0</version>
</dependency>
<dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
       <version>3.9</version>
</dependency>

JAVA代碼案例跨域

  1 package com.joyce.demo.jwt.controller;
  2 
  3 import java.util.Date;
  4 import java.util.HashMap;
  5 import java.util.Iterator;
  6 import java.util.Map;
  7 import java.util.Map.Entry;
  8 import javax.servlet.http.HttpServletRequest;
  9 import javax.servlet.http.HttpServletResponse;
 10 import org.apache.commons.lang3.StringUtils;
 11 import org.springframework.web.bind.annotation.RequestMapping;
 12 import org.springframework.web.bind.annotation.RestController;
 13 import io.jsonwebtoken.ExpiredJwtException;
 14 import io.jsonwebtoken.Jwts;
 15 import io.jsonwebtoken.MalformedJwtException;
 16 import io.jsonwebtoken.SignatureAlgorithm;
 17 import io.jsonwebtoken.SignatureException;
 18 import io.jsonwebtoken.UnsupportedJwtException;
 19 
 20 /**
 21  * jwt 官網: https://jwt.io
 22  * 
 23  * @author Joyce 朱文  2019/6/16
 24  *
 25  */
 26 @RestController
 27 public class JwtController {
 28 
 29     private static final String SECRET = "123456"; // jwt token私鑰,防止token被盜被破解
 30     public static final long EXPIRATION_TIME = 1800_000L; // token的過時時間,30 分鐘
 31 
 32     /**
 33      * <pre>
 34      * 步驟1:第一次訪問系統,生成token。
 35      * </pre>
 36      */
 37     @RequestMapping("/joyce/step1/firstAccess")
 38     public String step1(HttpServletRequest request, HttpServletResponse response) {
 39 
 40         // 把原來放在session裏的信息都放入token
 41         HashMap<String, Object> tokenDataMap = new HashMap<>();
 42         tokenDataMap.put("uuid", "避免把敏感信息寫入token");
 43         tokenDataMap.put("other", "xxx");
 44         request.getCookies();
 45 
 46         // 指定token的過時時間:30分鐘
 47         Date thisTokenExpTime = new Date(new Date().getTime() + EXPIRATION_TIME);
 48 
 49         // 生成jwt token
 50         String token = Jwts.builder().setClaims(tokenDataMap).setExpiration(thisTokenExpTime)
 51                 .signWith(SignatureAlgorithm.HS512, SECRET).compact();
 52 
 53         // 按照jwt官方說明,可把token放入header中的Authorization,而且Authorization type爲「Bearer Token」
 54         response.setCharacterEncoding("UTF-8");
 55         response.setContentType("application/json; charset=utf-8");
 56         response.setHeader("Access-Control-Allow-Headers", "Origin,Content-Type,Authorization");
 57         response.setHeader("Authorization", "Bearer " + token);
 58 //        response.setHeader("Access-Control-Allow-Origin","*");//啓用跨域
 59 //        response.setHeader("Access-Control-Allow-Credentials", "true");
 60 //        response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PATCH,PUT");
 61 //        response.setHeader("Access-Control-Max-Age", "3600");
 62 //        response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,x-requested-with,X-Custom-Header," +
 63 //                "Content-Type,Accept,Authorization");
 64 
 65         return token;
 66     }
 67 
 68     /**
 69      * <pre>
 70      * 步驟2:進入後續任何一個頁面 
 71      * 一、從Authorization header中獲取token 
 72      * 二、校驗token正確性,若是錯誤,返回提示信息
 73      * </pre>
 74      */
 75     @RequestMapping("/joyce/step2/validToken")
 76     public String step2(HttpServletRequest request, HttpServletResponse response) {
 77 
 78         // 獲取header
 79         String authorization = request.getHeader("Authorization");
 80         System.out.println("authorization===== " + authorization);
 81 
 82         // 解析token
 83         String token = StringUtils.EMPTY;
 84         // 若是token爲空,則返回失敗
 85         if (StringUtils.isBlank(authorization)) {
 86             return "error";
 87         }
 88 
 89         try {
 90             token = authorization.replaceFirst("Bearer ", StringUtils.EMPTY);
 91             // 獲得自定義數據
 92             Map<String, Object> tokenDataMap = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
 93 
 94             //////////////////////////////////// 取值方式一
 95             // 獲取token裏payload有效負載數據
 96             String uuid = (String) (tokenDataMap.get("uuid"));
 97             String other = (String) (tokenDataMap.get("other"));
 98 //                Date generateTime = new Date((Long) tokenDataMap.get("myDate"));
 99 
100             //////////////////////////////////// 取值方式二
101             Iterator<Entry<String, Object>> it = tokenDataMap.entrySet().iterator();
102             while (it.hasNext()) {
103                 Entry<String, Object> entry = it.next();
104                 System.out.println("entry = " + entry.getKey() + ":" + entry.getValue());
105             }
106 
107             // 對全部的異常都須要進行業務處理
108         } catch (UnsupportedJwtException e) { // 當接收到的JWT格式/配置與應用程序指望的格式不匹配時拋出異常。例如,當應用程序須要一個加密簽名的JWS聲明時,若是解析一個無簽名的明文JWT,則會引起此異常。
109             // TODO: handle exception
110         } catch (MalformedJwtException e) { // 非正確的jwt結構
111             // TODO: handle exception
112         } catch (SignatureException e) { // 簽名錯誤
113             // TODO: handle exception
114         } catch (ExpiredJwtException e) { // token過時
115             // TODO: handle exception
116         } catch (IllegalArgumentException e) { // 傳遞非法參數
117             // TODO: handle exception
118         }
119         return "ok";
120     }
121 
122 }

 end.cookie

相關文章
相關標籤/搜索