這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
0x0 什麼是jwt
JWT是JSON Web Token的縮寫,可以用作授權認證。傳統的授權認證一般採用session,由於session儲存在服務端,加大了服務端的計算量,
而且多台伺服器之間存在著session同步的問題。而JWT儲存在用戶端,不僅減少了服務端的計算量,而且天生支援分布式。
0x1 jwt的結構
JWT由三部分組成:
Header:頭部,表明類型和密碼編譯演算法
Claims:聲明,即載荷(承載的內容)
Signature:簽名,這一部分是將header和claims進行base64轉碼後,並用header中聲明的密碼編譯演算法加鹽(secre)後構成。
即:
tmpstr = base64(header)+base64(claims)
signature = encrypt(tmpstr,secret)
最後三者用"."串連,即:
token = base64(header).base64(claims).signature
詳細的介紹可以看jwt中文文檔.
另外jwt官網有調試工具,可以輔助查錯。
0x2 在web中如何使用
用戶端發送登入請求(這個登入請求是不需要jwt驗證的),在登入請求裡返回token。
用戶端把token儲存起來,以後其它需要token的請求就在header裡帶上token。
0x3 實戰
在echo架構中使用jwt
這裡是官方文檔和教程,說的比較清楚了。
我們僅需要在登入介面裡產生jwt的token,並返回,jwt中介軟體會自動幫我們做jwt的驗證。可以把先做分組路由,在分組裡使用jwt中介軟體。
如果不使用架構,可以直接用jwt-go
配合axios.js
我們的前端使用了vue+axios,他嫌每次都拼接header麻煩,於是幫他在網上查了一下,可以配置axios為自動添加header。
axios的代碼如下:參考了這篇部落格
require('es6-promise').polyfill(); // 引入一次就行import axios from 'axios';// 建立 axios 執行個體const Axios = axios.create({ baseURL: 'your base url', timeout: 5000, });Axios.interceptors.request.use( config => { if (config.method === 'post') { const formData = new FormData(); Object.keys(config.data).forEach(key => formData.append(key, config.data[key])); config.data = formData; } if (config.url !="/login" && localStorage.token != undefined ){ config.headers.Authorization = 'Bearer ' + localStorage.token; } return config; }, error => { return Promise.reject(error); });Axios.interceptors.response.use( res => { return Promise.resolve(res); }, error => { return Promise.reject(error); });// 將 Axios 執行個體添加到Vue的原型對象上export default { install(Vue) { Object.defineProperty(Vue.prototype, '$Axios', { value: Axios }); }};
注意if (config.method === 'post') 這裡是把post過去的資料轉為表單,如果不加這一句,提交過去的是文本了,在伺服器端無法用getpost(key)這種方式擷取參數了。
0x4 調試
要善於利用官網調試工具,我便在jwt加密上掉坑裡了。
加密時使用的是HS256,而驗證時用的是HS512。
0x5 擴充
由於jwt載荷使用的是base64編碼,可以很容易被破解,所以不要放入敏感資訊,也不建議放入過多的資訊。
jwt裡可以存到期時間,所以可以用來做時效性的應用,而且不需要使用資料庫。
另外也要避免jwt的重放攻擊。