學習筆記:JWT在spring中的時間


轉自:http://blog.csdn.net/ahmuamu/article/details/52216349(謝謝樓主分享)

spring安全驗證之jwt(json web token)實踐

系統開發來講,安全驗證永遠是最重要的,從最原始的session、cookie驗證方式,到符合restful風格、滿足前后端分離需求、啟用https請求,各方面都在不斷變化中。本文以jwt(json web token)的實踐為例,介紹一二。

首先,來看一下jwt的概念,流程圖如下所示:

流程圖

用戶發起登錄請求,服務端創建一個加密后的jwt信息,作為token返回值,在后續請求中jwt信息作為請求頭,服務端正確解密后可獲取到存儲的用戶信息,表示驗證通過;解密失敗說明token無效或者已過期。

加密后jwt信息如下所示,是由.分割的三部分組成,分別為Header、Payload、Signature。

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJqd3QiLCJpYXQiOjE0NzEyNzYyNTEsInN1YiI6IntcInVzZXJJZFwiOjEsXCJyb2xlSWRcIjoxfSIsImV4cCI6MTQ3MTMxOTQ1MX0.vW-pPSl5bU4dmORMa7UzPjBR0F6sqg3n3hQuKY8j35o

Header包含兩部分信息,alg指加密類型,可選值為HS256、RSA等等,typ=JWT為固定值,表示token的類型。

{
    "alg": "HS256",
    "typ": "JWT"
}

Payload是指簽名信息以及內容,一般包括iss (發行者), exp (過期時間), sub(用戶信息), aud (接收者),以及其他信息,詳細介紹請參考官網。

{
    "sub": "1234567890",
    "name": "John Doe",
    "admin": true
}

Signature則為對Header、Payload的簽名。

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

在jwt官網,可以看到有不同語言的實現版本,這里使用的是java版的jjwt。話不多說,直接看代碼,加解密都很簡單:

/**
  * 創建 jwt
  * @param id
  * @param subject
  * @param ttlMillis
  * @return
  * @throws Exception
  */
  public String createJWT(String id, String subject, long ttlMillis) throws Exception {
       SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256 ;
       long nowMillis = System. currentTimeMillis();
       Date now = new Date( nowMillis);
       SecretKey key = generalKey();
       JwtBuilder builder = Jwts. builder()
            .setId(id)
            .setIssuedAt(now)
            .setSubject(subject)
           .signWith(signatureAlgorithm, key);
       if (ttlMillis >= 0){
           long expMillis = nowMillis + ttlMillis;
           Date exp = new Date( expMillis);
           builder.setExpiration( exp);
       }
       return builder.compact();
 }

  /**
  * 解密 jwt
  * @param jwt
  * @return
  * @throws Exception
  */
  public Claims parseJWT(String jwt) throws Exception{
       SecretKey key = generalKey();
       Claims claims = Jwts. parser()
          .setSigningKey( key)
          .parseClaimsJws( jwt).getBody();
       return claims;
 }

加解密的key是通過固定字符串轉換而生成的;subject為用戶信息的json字符串;ttlMillis是指token的有效期,時間較短,需要定時更新。

這里要介紹的token刷新方式,是在生成token的同時生成一個有效期較長的refreshToken,后續由客戶端定時根據refreshToken來獲取最新的token。瀏覽器與服務端之間建立sse(server send event)請求,來實現刷新。關於sse在前面博文中有介紹過,此處略過不提。

本文完整源代碼存放於github,地址:https://github.com/ahmu/spring-authorization-demo

參考資料:

1.jwt官方網站:https://jwt.io/

2.jjwt項目:https://github.com/jwtk/jjwt

3.Introduction to JSON Web Tokens:https://jwt.io/introduction/

4.How to Create and verify JWTs in Java: https://stormpath.com/blog/jwt-java-create-verify


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com