文档章节

用 Redis 处理 jsonwebtoken 生成的 Token

开源中国匿名会员
 开源中国匿名会员
发布于 2014/06/19 10:13
字数 701
阅读 9393
收藏 9
点赞 1
评论 2

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

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

react技术栈实践(从前到后撸一个电影搜集应用)

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

xiyuyizhi ⋅ 2017/12/17 ⋅ 0

koa 实现 jwt 认证

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

superman666 ⋅ 2017/11/26 ⋅ 0

Express + JWT用户认证最轻实践

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

luffyZhou ⋅ 05/28 ⋅ 0

使用 AngularJS & NodeJS 实现基于 token 的认证应用

传统的认证系统 在开始说基于 token 的认证系统之前,我们先看一下传统的认证系统。 用户在登录域输入 用户名 和 密码 ,然后点击 登录 ; 请求发送之后,通过在后端查询数据库验证用户的合法...

大糊涂 ⋅ 2015/06/22 ⋅ 1

springmvc下的基于token的防重复提交

问题描述: 现在的网站在注册步骤中,由于后台要处理大量信息,造成响应变慢(测试机器性能差也是造成变慢的一个因素),在前端页面提交信息之前,等待后端响应,此时如果用户 再点一次提交按...

凯文加内特 ⋅ 2015/07/31 ⋅ 3

大牛们能看看我写的一个生产有时效性的token存储到redis的方法,请大家指出不足还有给出建议

restful风格api 架构师说全部用token来控制访问权限,就是访问前都要核对token的值,所以项目集成redis,把生成的token放进redis里面保管就因为redis可以控制token的时间,这其实我考虑到如果...

学编程的小伟 ⋅ 2017/07/06 ⋅ 3

分布式锁原理及常用实现

起因 前段时间,看到redis作者发布的一篇文章《Is Redlock safe?》,Redlock是redis作者基于redis设计的分布式锁的算法。文章起因是有一位分布式的专家写了一篇文章《How to do distributed...

偶尔诗文 ⋅ 2016/11/09 ⋅ 0

oauth2.0服务的开发-code、token的维持与验证

oauth2.0还比较新,中英文文档都比较少,网上的都是调用oauth2接口文档。 oauth官网似乎只规定了接口参数和返回值,也没有定义如何生成token,以及验证和维持。 问:开发类似新浪微博这种oau...

zhang1hang2 ⋅ 2013/08/19 ⋅ 3

淘淘商城系列——单点登录之用户登录

我们先来看下用户登录流程图,如下图所示。用户登录涉及到三个部分,第一部分是淘淘商城前台工程,第二部分是单点登录服务,第三部分是Redis服务。具体流程下图已经说的很明白了,我就不再啰...

yerenyuan_pku ⋅ 2017/06/14 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

DevOps 资讯 | PostgreSQL 的时代到来了吗 ?

PostgreSQL是对象-关系型数据库,BSD 许可证。拼读为"post-gress-Q-L"。 作者: Tony Baer 原文: Has the time finally come for PostgreSQL?(有删节) 近30年来 PostgreSQL 无疑是您从未听...

RiboseYim ⋅ 13分钟前 ⋅ 0

Cube、Cuboid 和 Cube Segment

1.Cube (或Data Cube),即数据立方体,是一种常用于数据分析与索引的技术;它可以对原始数据建立多维度索引。通过 Cube 对数据进行分析,可以大大加快数据的查询效率 2.Cuboid 在 Kylin 中特...

无精疯 ⋅ 51分钟前 ⋅ 0

github太慢

1:用浏览器访问 IPAddress.com or http://tool.chinaz.com 使用 IP Lookup 工具获得github.com和github.global.ssl.fastly.net域名的ip地址 2:/etc/hosts文件中添加如下格式(IP最好自己查一...

whoisliang ⋅ 53分钟前 ⋅ 0

非阻塞同步之 CAS

为解决线程安全问题,互斥同步相当于以时间换空间。多线程情况下,只有一个线程可以访问同步代码。这种同步也叫阻塞同步(Blocking Synchronization). 这种同步属于一种悲观并发策略。认为只...

长安一梦 ⋅ 今天 ⋅ 0

云计算的选择悖论如何对待?

人们都希望在工作和生活中有所选择。但心理学家的调查研究表明,在多种选项中进行选择并不一定会使人们更快乐,甚至不会产生更好的决策。心理学家Barry Schwartz称之为“选择悖论”。云计算为...

linux-tao ⋅ 今天 ⋅ 0

Redis 注册为 Windows 服务

Redis 注册为 Windows 服务 redis 注册为 windows 服务相关命令 注册服务 redis-server.exe –service-install redis.windows.conf 删除服务 redis-server –service-uninstall 启动服务 re......

Os_yxguang ⋅ 今天 ⋅ 0

世界那么大,语言那么多,为什么选择Micropython,它的优势在哪?

最近国内MicroPython风靡程序界,是什么原因导致它这么火呢?是因为他功能强大,遵循Mit协议开源么? 错!因为使用它真的是太舒服了!!! Micropython的由来,这得益于Damien George这位伟大...

bodasisiter ⋅ 今天 ⋅ 0

docker 清理总结

杀死所有正在运行的容器 docker kill $(docker ps -a -q) 删除所有已经停止的容器(docker rm没有加-f参数,运行中的容器不会删掉) docker rm $(docker ps -a -q) 删除所有未打 dangling 标...

vvx1024 ⋅ 今天 ⋅ 0

关于学习

以前学车的时候,教练说了这样的一句话:如果一个人坐在车上一直学,一直学,反而不如大家轮流着学。因为一个人一直学,就没有给自己留空间来反思和改进。而轮流着学的时候大家下来之后思考上...

mskk ⋅ 今天 ⋅ 0

压缩工具之gzip-bzip2-xz

win下常见压缩工具:rar zip 7z linux下常见压缩工具:zip gz bz2 xz tar.gz tar.bz2 tar.xz gzip 不支持目录压缩 gzip 1.txt #压缩。执行后1.txt消失,生成1.txt.gz压缩文件 gzip -d 1.txt....

ZHENG-JY ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部