文档章节

用 Redis 处理 jsonwebtoken 生成的 Token

开源中国匿名会员
 开源中国匿名会员
发布于 2014/06/19 10:13
字数 701
阅读 9512
收藏 9

作者好牛逼啊,我不懂的他全都懂。

Use Redis to revoke Tokens generated from jsonwebtoken


前面一篇文章中,我讲述了怎么用 AngularJS 和 NodeJS 通过 jsonwebtoken 做用户验证。有人说,就算点了 logout 按钮, 你把 token 从 Angular 页面的 AuthenticationService 上移掉,你还是能用这个有效的 Token 来访问 API,直到 jsonwebtoken 判定它过期为止。

为了防止这种丑行,我决定用 Redis 数据库 来处理 token,当用户点了 logout 按钮的时候。Token 只会保存一段时间,就是你用 jsonwebtoken 登陆之后,token 有效的这段时间。之后,token 会被 redis 自动删掉。最后,我们创建一个 nodejs 的中间件,检查所有受限 endopoint 用的 token 是否存在 Redis 数据库中。

为 NodeJS 配置 Reids

首先我们要为 nodejs 安装 Redis 客户端库,并且配置我们的客户端链接到 Redis 实例。当 nodejs 应用启动的时候:

<!-- lang: js -->
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;

然后,我们来创建一个方法,用来检查提供的 token 是不是被注销了。

Token 管理和中间件

为了在 Redis 中保存 Token,我们要创建一个方法来拿到请求中的 Header 的 Token 参数,然后把它作为 Redis 的 key 保存起来。值是什么我们不管它。

<!-- lang: js -->
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;
    }
};

然后,再创建一个中间件来验证一下 token,当用户发起请求的时候:

<!-- lang: js -->
// Middleware for token verification
exports.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 这个方法,是一个中间件,用来拿到请求头中的 token,然后在 Redis 里面查找它。如果 token 被发现了,我们就发 HTTP 401.否则我们就继续工作流,让请求访问 API。

我们要在用户点 logout 的时候,执行 expireToken 方法:

<!-- lang: js -->
exports.logout = function(req, res) {
    if (req.user) {
        tokenManager.expireToken(req.headers);
 
        delete req.user;
        return res.send(200);
    }
    else {
        return res.send(401);
    }
}

最后我们更新路由,用上新的中间件:

<!-- lang: js -->
//Login
app.post('/user/signin', routes.users.signin);
 
//Logout
app.get('/user/logout', jwt({secret: secret.secretToken}), routes.users.logout);
 
//Get all posts
app.get('/post/all', jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.listAll);
 
//Create a new post
app.post('/post', jwt({secret: secret.secretToken}), tokenManager.verifyToken , routes.posts.create);
 
//Edit the post id
app.put('/post', jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.update);
 
//Delete the post id
app.delete('/post/:id', jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.delete);

好了,现在我们每次发送请求的时候,我们都去解析 token, 然后看看是不是有效的。

你可以从这里拿到源码

© 著作权归作者所有

共有 人打赏支持
开源中国匿名会员
粉丝 78
博文 104
码字总数 113453
作品 2
徐汇
技术主管
加载中

评论(2)

流云飞华
谢谢楼主,帮助我解决问题了
Hanks
Hanks
83 正是要看的那部分信息,谢谢~
react技术栈实践(我们也应该会点后端)-一个电影webApp

之前做了个电影搜集的小应用,前端采用react,后端采用express+mongodb,最近又将组件间的状态管理改成了redux,并加入了redux-saga来管理异步操作,记录一些总结 在线地址 源码 主要功能 爬取...

xiyuyizhi
2017/12/17
0
0
react技术栈实践(从前到后撸一个电影搜集应用)

之前做了个电影搜集的小应用,前端采用react,后端采用express+mongodb,最近又将组件间的状态管理改成了redux,并加入了redux-saga来管理异步操作,记录一些总结 在线地址 源码 主要功能 爬取...

xiyuyizhi
2017/12/17
0
0
Node.js 应用:Koa2 使用 JWT 进行鉴权

前言 在前后端分离的开发中,通过 Restful API 进行数据交互时,如果没有对 API 进行保护,那么别人就可以很容易地获取并调用这些 API 进行操作。那么服务器端要如何进行鉴权呢? Json Web T...

_林鑫
08/17
0
0
koa 实现 jwt 认证

关于 Token 认证机制,这里不做更多解释。不清楚的可以看我的这篇文章:Web开发中常见的认证机制 GitHub 地址:koa-jwt-sample 所需库 bcrypt - 用于加密密码 koa-jwt - jwt 中间件 jsonwebt...

superman666
2017/11/26
0
0
Express + JWT用户认证最轻实践

最近给自己列了一个list,Ummm...列来列去大概是下面这个样子: React SSR服务端渲染 jwt用户认证 Vue全家桶 微信小程序开发 ... 等等 好吧,谁让自己菜呢,没什么好抱怨的,一个一个来吧。正...

luffyZhou
05/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Linux下如何查看版本信息

Linux下如何查看版本信息, 包括位数、版本信息以及CPU内核信息、CPU具体型号等等,整个CPU信息一目了然。  1、# uname -a (Linux查看版本当前操作系统内核信息)   Linux localhost.l...

15834278076
29分钟前
0
0
单点登录 SSO 的实现原理

单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。 单点登录在大型网站里...

明理萝
30分钟前
1
1
虚拟机性能监控工具

前言 JVM调优流行这么一句话“无监控不调优”,因为如果没有监控,就不知道虚拟机的运行状况。更谈不上调优了,所以,学习和了解Java 虚拟机的监控工具很有必要。 概述 在Java虚拟机中经常用...

kukudeku
39分钟前
1
0
一行搞定electron和jquery冲突,electron和jquery最简单和完美的兼容方法

electron和jquery的常见报错: Uncaught ReferenceError: $ is not defined 解决方法:在jquery最末端加上这样一行判断即可. <script src="https://code.jquery.com/jquery-2.2.0.min.js"></s......

xiaogg
49分钟前
1
0
GC和内存管理

1、垃圾回收器需要关注的内容 ava运行时内存区域的各个部分中,程序计数器、虚拟机栈、本地方法栈这三个区域的生命周期和线程相关,栈中的栈帧随着方法的进入和退出执行着进栈和出栈,每一个...

京一
56分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部