jwt 0.9.0(三)jwt客户端存储状态可行性分析,及Java代码案例

Jwt客户端存储状态可行性分析

1、前端首次访问后台,后台生成token,放在http header的Authorization里(官网推荐,可解决跨域cookie跨域问题),并且Authorization Type类型为Bearer,将token返回给前端。

2、后台生成token的过程,包括给token指定加密协议比如HS56,加密类型比如“JWT”,自定义数据比如uuid,还有最重要的是记得指定一个超级复杂的密钥,并且定期更换它,密钥用于jwt签名部分。还需要给jwt token指定一个合理的过期时间,这个也同样非常重要。

3、前端获取token后存储token,建议存入本地cookie。

4、前端再次发起后台API接口访问,此时需要带上token,也是放在http header中且Authorization Type类型为Bearer,后台需校验token的正确性后才可访问权限受限的API接口或其他资源。

先添加maven依赖

<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      * 1、从Authorization header中获取token 
 72      * 2、校验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.

posted on 2019-06-17 22:09  梦幻朵颜  阅读(1198)  评论(2编辑  收藏  举报