怪我咯2017-04-17 14:54:44
1.首先你要知道koa-jwt
的功能,目前只提供了decode
, sign
和verify
的功能,你說的判斷token
過期koa-jwt
module沒有專門提供函數來驗證。
2.那如何判斷token
過期了呢? 先簡單跟你介紹jwt
,然後再教你如何判斷過期。
2.1 jwt
簡介
JSON Web Token(jwt
) 在網頁中,許多操作都需要驗證使用者權限,判斷使用者是否登陸等。一般有兩種實現方式: 一種是透過session
和cookie
; 另一種就是用鑑權token
。利用token
來鑑權主要有以下兩個優勢。
服務端不需要請求DB來取得使用者訊息,因為使用者資訊已經存在token裡面。
token鑑權的方式對行動端和PC端同樣適用,服務端不需要維護兩套鑑權機制。
一個標準的jwt是由3個部分組成 <header>
, <payload>
和 <signature>
Header: base64編碼的json object, 包括使用的加密演算法等。
Payload: base64編碼的json object, 儲存使用者相關的資訊。
Signature: 根據Header,PayloadA 和一個金鑰(只有服務端知道),並利用Header中指定的加密演算法,產生的一個簽章字串。
2.2 如何判斷失效
判斷token過期有許多方法,我在這裡列出幾種供你選擇
jwt 提供了過期參數設置,在簽發token的時候(koa-jwt調用sign的時候),在Payload裡面設置exp
屬性,這是jwt提供的Registered Claims
(保留聲明), 記住一定要比當前時間大才行,如設定成當前時間之後10分鐘過期
{
exp: Date.now()+10*60*1000,
}
然後你可以持久化
儲存到你的localstorage, sessionStorage或cookie裡面,這個token透過請求傳到服務端,驗證(呼叫koa-jwt的verify的時候)的時候就會報TokenExpiredError
Thrown error if the token is expired.
Error object:
- name: 'TokenExpiredError'
- message: 'jwt expired'
- expiredAt: [ExpDate]
服務端產生token之後,你可以在請求的回傳裡面,把這個token存到cookie(或sessionStorage)裡面, 然後設定這個cookie的過期時間expire
, 這樣下次請求你在你的請求的header
或body
裡面拿不到token的時候就知道token過期了(和你提供的代碼類似,不過記得設定儲存token的這個cookie的過期時間)。
自訂類似exp
的屬性,因為exp
是保留屬性,所以你可以設定一個origin-iat
上次頒發的時間,然後持久化存儲,之後解出token之後,判斷當前時間和origin-iat
的時間差有沒有達到你的過期時間,達到了就重新要求鑑權,重新頒發token, 偽代碼如下
var profile = jwt.verify(req.header.token || req.body.token, secret);
// if more than 7 days old, force login
if (Date().now() - profile.original_iat > 7 * 24 * 60 * 60 * 1000) { // iat == issued at
return res.status(401).json({ isError: true, error: { message: 'Access Forbidden'}}); // re-logging
}
幾種方式的差別是: 第一種和第三種方式透過請求可以一直取到token,但是token可能是過期的。 第二種方式是透過請求可能取得不到token。 你自己可以根據你的業務需求做出合適的選擇。
附: JSON Web Token Specification RFC 7519