文档章节

用 Redis 处理 jsonwebtoken 生成的 Token

开源中国匿名会员
 开源中国匿名会员
发布于 2014/06/19 10:13
字数 701
阅读 9707
收藏 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技术栈实践(从前到后撸一个电影搜集应用)

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

xiyuyizhi
2017/12/17
0
0
react技术栈实践(我们也应该会点后端)-一个电影webApp

之前做了个电影搜集的小应用,前端采用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
gf-top/vue-koa2

vue-koa2 server篇 vue2,koa2和mongo搭建的单用户博客 目录设计 app.js -------- 入口文件 models -------- 数据库模型 controllers --------- 完成逻辑处理的控制器 middlewares --------- ...

gf-top
09/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring源码学习笔记-1-Resource

打算补下基础,学习下Spring源码,参考书籍是《Spring源码深度解析》,使用版本是Spring 3.2.x,本来想试图用脑图记录的,发现代码部分不好贴,还是作罢,这里只大略记录下想法,不写太细了 ...

zypy333
今天
10
0
RestClientUtil和ConfigRestClientUtil区别说明

RestClientUtil directly executes the DSL defined in the code. ConfigRestClientUtil gets the DSL defined in the configuration file by the DSL name and executes it. RestClientUtil......

bboss
今天
17
0

中国龙-扬科
昨天
2
0
Linux系统设置全局的默认网络代理

更改全局配置文件/etc/profile all_proxy="all_proxy=socks://rahowviahva.ml:80/"ftp_proxy="ftp_proxy=http://rahowviahva.ml:80/"http_proxy="http_proxy=http://rahowviahva.ml:80/"......

临江仙卜算子
昨天
10
0
java框架学习日志-6(bean作用域和自动装配)

本章补充bean的作用域和自动装配 bean作用域 之前提到可以用scope来设置单例模式 <bean id="type" class="cn.dota2.tpye.Type" scope="singleton"></bean> 除此之外还有几种用法 singleton:......

白话
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部