踩坑之路---JWT驗證


  • 使用JWT驗證客戶的攜帶的token
  • 客戶端在請求接口時,需要在request的head中攜帶一個token令牌
  • 服務器拿到這個token解析獲取用戶資源,這里的資源是非重要的用戶信息


目前我的理解,用於校驗的幾種方式

1. 攔截器
2. SpringSecurity驗證(目前沒有弄懂)
3. shiro攔截驗證

攔截器
配置好攔截器后,過濾掉無需驗證的接口,其他的接口在請求的時候,獲取其token然后解析是否是正確的客戶端資源
SrpingSecurity
SpringSecurity就麻煩多了...此處省略1000字
Shiro自定義認證
shiro在自定義realm中有兩個方法,一個是認證,一個是授權,在其認證的方法內驗證其token

重點

上面說的只是個流程,最主要的是jwt怎么做token的編碼和解碼的
        long expire = 680090;
        String  = "123";
這里有兩個需要注意的地方,就是設置過期時間和鹽

過期時間是驗證token的有效時間,在自己手動設置過期時間內是有效的,超過此時間,jwt就無法解析其token了
 其次是鹽,這是個字符串常量,也可以動態生成鹽,放入數據庫中在驗證的時候獲取解析,這里需要將其詞符串設置成Base64編碼,不然會解析錯誤..(大坑)這里使用的是apache的codec來編碼字符串,也可使用java自帶的Base64工具編碼

生成token

    

 /**
     * 生成jwt token
     */
    public String generateToken(long userId) {
        Date nowDate = new Date();
        //過期時間
        Date expireDate = new Date(nowDate.getTime() + expire * 1000);

        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS512;
        //生成加密密鑰
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubjectsecret(userId+"")
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(signatureAlgorithm, new String(org.apache.commons.codec.binary.Base64.encodeBase64(secret.getBytes())))
                .compact();
    }

ps: 在這里傳入的是用戶id,這在解碼后通過getSubject()方法可以獲取到,如果需要傳入用戶的多個信息也可以設置成

     .claim("info",userInfo)
     .claim("id",userId)
獲取

    @Test
    public void jwt(){
        String s = generateToken(1,"小明");
        System.out.println(s);
        Claims claimByToken = getClaimByToken(s);
        System.out.println(claimByToken.get("info")+"--"+claimByToken.get("id"));
    }
    resut:            eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpbmZvIjoi5bCP5piOIiwiaWQiOjEsImlhdCI6MTU0NDg4NTQyOCwiZXhwIjoxNTQ1NTY1NTE4fQ.4SvjebEFd4lixC1jHgyMpQrlPoQz8DI0BTFYsGY0GsPKx_dc7GfDLR2qd_mi46mLpDvJ0HCatfEmhb7w7y9xrA

    小明--1

解析token

 /**
     * 解析token
     *
     * @param token
     * @return
     */
    public  Claims getClaimByToken(String token) {
        String secret = "123";
        try {
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS512;
            return Jwts.parser()
                    .setSigningKey(new String(org.apache.commons.codec.binary.Base64.encodeBase64("123".getBytes())))
                    .parseClaimsJws(token)
                    .getBody();
        }catch (Exception e){
            System.out.println("jwt 解密失敗");
            return null;
        }
    }

 

ps:目前解決了基本問題,shiro+jwt 就很NICE-__- 

至於SpringSecurity:還是要多多學習了.....


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM