系統開發來說,安全驗證永遠是最重要的,從最原始的session、cookie驗證方式,到符合restful風格、知足先後端分離需求、啓用https請求,各方面都在不斷變化中。本文以jwt(json web token)的實踐爲例,介紹一二。html
首先,來看一下jwt的概念,流程圖以下所示:java
用戶發起登陸請求,服務端建立一個加密後的jwt信息,做爲token返回值,在後續請求中jwt信息做爲請求頭,服務端正確解密後可獲取到存儲的用戶信息,表示驗證經過;解密失敗說明token無效或者已過時。git
加密後jwt信息以下所示,是由.分割的三部分組成,分別爲Header、Payload、Signature。github
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJqd3QiLCJpYXQiOjE0NzEyNzYyNTEsInN1YiI6IntcInVzZXJJZFwiOjEsXCJyb2xlSWRcIjoxfSIsImV4cCI6MTQ3MTMxOTQ1MX0.vW-pPSl5bU4dmORMa7UzPjBR0F6sqg3n3hQuKY8j35o
Header包含兩部分信息,alg指加密類型,可選值爲HS25六、RSA等等,typ=JWT爲固定值,表示token的類型。web
{ "alg": "HS256", "typ": "JWT" }
Payload是指簽名信息以及內容,通常包括iss (發行者), exp (過時時間), sub(用戶信息), aud (接收者),以及其餘信息,詳細介紹請參考官網。spring
{ "sub": "1234567890", "name": "John Doe", "admin": true }
Signature則爲對Header、Payload的簽名。json
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)http://www.cnblogs.com/xiekeli/p/5607107.html
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