標籤:接下來 class create 首頁 blog 避免 nod 管理器 ddl
利用Redis撤銷JSON Web Token產生的令牌
chszs。著作權全部。未經允許,不得轉載。博主首頁:http://blog.csdn.net/chszs
早先的博文討論了在Angular.js和Node.js中使用jsonwebtoken實現認證授權的案例。這裡要說明一下,當使用者點擊了“登出”button,使用者的令牌在Angular端會從授權認證服務AuthenticationService中移除,可是此令牌仍舊是有效,還能夠被攻擊者竊取到。用於API調用,直至jsonwebtoken的有效時間結束。
為了避免此情況的發生。能夠使用Redis資料庫來儲存已撤銷的令牌——當使用者點擊登出button時。且令牌在Redis儲存的時間與令牌在jsonwebtoken中定義的有效時間同樣。當有效時間到了後。令牌會自己主動被Redis刪除。最後,建立Node.js應用來檢查各終端上傳的令牌在Redis中是否存在。
一、在Node.js中配置Redis
首先,必須在Node.js中安裝Redisclient串連庫。並配置client能夠串連到Redis執行個體。
例如以下:
var redis = require(‘redis‘);var redisClient = redis.createClient(6379);redisClient.on(‘error‘, function (err) { console.log(‘Error ‘ + err);});redisClient.on(‘connect‘, function () { console.log(‘Redis is ready‘);});exports.redis = redis;exports.redisClient = redisClient;
二、令牌管理器&中介軟體
要儲存已移除的令牌。須要建立一個函數來擷取Header的參數,並取出令牌,把它作為鍵名儲存到Redis。至於索引值就無所謂了。
var redisClient = require(‘./redis_database‘).redisClient;var TOKEN_EXPIRATION = 60;var TOKEN_EXPIRATION_SEC = TOKEN_EXPIRATION * 60;exports.expireToken = function(headers) { var token = getToken(headers); if (token != null) { redisClient.set(token, { is_expired: true }); redisClient.expire(token, TOKEN_EXPIRATION_SEC); }};var getToken = function(headers) { if (headers && headers.authorization) { var authorization = headers.authorization; var part = authorization.split(‘ ‘); if (part.length == 2) { var token = part[1]; return part[1]; } else { return null; } } else { return null; }};
接下來。能夠建立一個中介軟體來驗證使用者提供的令牌是否有效:
// Middleware for token verificationexports.verifyToken = function (req, res, next) { var token = getToken(req.headers); redisClient.get(token, function (err, reply) { if (err) { console.log(err); return res.send(500); } if (reply) { res.send(401); } else { next(); } });};
方法verifyToken是一個中介軟體,它從請求的Header部分取出令牌,並在Redis中進行查詢。假設令牌發現了。則響應HTTP 401。
否則,繼續處理,讓使用者訪問受限制的API。
當使用者點擊登出button時。平台端必須調用expireToken方法。
exports.logout = function(req, res) { if (req.user) { tokenManager.expireToken(req.headers); delete req.user; return res.send(200); } else { return res.send(401); }}
最後,讓之前開發的中介軟體模組生效:
//Loginapp.post(‘/user/signin‘, routes.users.signin);//Logoutapp.get(‘/user/logout‘, jwt({secret: secret.secretToken}), routes.users.logout);//Get all postsapp.get(‘/post/all‘, jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.listAll);//Create a new postapp.post(‘/post‘, jwt({secret: secret.secretToken}), tokenManager.verifyToken , routes.posts.create);//Edit the post idapp.put(‘/post‘, jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.update);//Delete the post idapp.delete(‘/post/:id‘, jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.delete);
如今,每次使用者要請求受限的服務時,我們都須要解密其令牌,並檢查令牌是否被撤銷。
利用Redis撤銷JSON Web Token產生的令牌