利用Redis撤销JSON Web Token产生的令牌

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 利用Redis撤销JSON Web Token产生的令牌 早先的博文讨论了在Angular.js和Node.js中使用jsonwebtoken实现认证授权的案例。这里要说明一下,当用户点击了“注销”按钮,用户的令牌在Angular端会从授权认证服务AuthenticationService中移除,但是此令牌仍旧是有效的,还可以被攻击者窃取到,用于API调用,直至jsonwebtoken的有效时间结束。

利用Redis撤销JSON Web Token产生的令牌

早先的博文讨论了在Angular.js和Node.js中使用jsonwebtoken实现认证授权的案例。这里要说明一下,当用户点击了“注销”按钮,用户的令牌在Angular端会从授权认证服务AuthenticationService中移除,但是此令牌仍旧是有效的,还可以被攻击者窃取到,用于API调用,直至jsonwebtoken的有效时间结束。

为了避免此情况的发生,可以使用Redis数据库来存储已撤销的令牌——当用户点击注销按钮时。且令牌在Redis存储的时间与令牌在jsonwebtoken中定义的有效时间相同。当有效时间到了后,令牌会自动被Redis删除。最后,创建Node.js应用来检查各终端上传的令牌在Redis中是否存在。

一、在Node.js中配置Redis

首先,必须在Node.js中安装Redis客户端连接库,并配置客户端能够连接到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 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是一个中间件,它从请求的Header部分取出令牌,并在Redis中进行查询。如果令牌发现了,则响应HTTP 401。否则,继续处理,让用户访问受限制的API。

当用户点击注销按钮时,平台端必须调用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);
    }
} 

最后,让之前开发的中间件模块生效:

//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); 

现在,每次用户要请求受限的服务时,我们都需要解密其令牌,并检查令牌是否被撤销。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
3月前
|
XML JSON 前端开发
【Web前端揭秘】XML与JSON:数据界的双雄对决,你的选择将如何改写Web世界的未来?
【8月更文挑战第26天】本文深入探讨了XML和JSON这两种广泛使用的数据交换格式在Web前端开发中的应用。XML采用自定义标签描述数据结构,适用于复杂层次数据的表示,而JSON则以键值对形式呈现数据,更为轻量且易解析。通过对两种格式的示例代码、结构特点及应用场景的分析,本文旨在帮助读者更好地理解它们的差异,并根据实际需求选择最合适的数据交换格式。
58 1
|
3月前
|
JSON 前端开发 JavaScript
|
1月前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
24 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
30天前
|
存储 JSON 前端开发
JSON与现代Web开发:数据交互的最佳选择
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也便于机器解析和生成。它以文本格式存储数据,常用于Web应用中的数据传输,尤其是在客户端和服务器之间。
42 0
|
3月前
|
存储 JSON JavaScript
震撼!Cookie、Session、Token、JWT 终极对决:揭开 Web 认证的神秘面纱!
【8月更文挑战第13天】Web 开发中,Cookie、Session、Token 和 JWT 常混淆。Cookie 是服务器给客户端的小信息片,如登录状态,每次请求都会返回。Session 则是服务器存储的用户数据,通过 Session ID 追踪。Token 类似通行证,证明客户端身份且可加密。JWT 是结构化的 Token,含头部、载荷及签名,确保数据完整性和安全性。
66 4
|
3月前
|
JSON JavaScript 前端开发
Unexpected token u in JSON at position 0
这篇文章解释了JavaScript中"Unexpected token u in JSON at position 0"错误的常见原因,通常是由于尝试解析undefined变量导致的,并建议检查是否有变量在JSON.parse()执行时未赋值或值为undefined。
Unexpected token u in JSON at position 0
|
3月前
|
Java Spring 容器
彻底改变你的编程人生!揭秘 Spring 框架依赖注入的神奇魔力,让你的代码瞬间焕然一新!
【8月更文挑战第31天】本文介绍 Spring 框架中的依赖注入(DI),一种降低代码耦合度的设计模式。通过 Spring 的 DI 容器,开发者可专注业务逻辑而非依赖管理。文中详细解释了 DI 的基本概念及其实现方式,如构造器注入、字段注入与 setter 方法注入,并提供示例说明如何在实际项目中应用这些技术。通过 Spring 的 @Configuration 和 @Bean 注解,可轻松定义与管理应用中的组件及其依赖关系,实现更简洁、易维护的代码结构。
51 0
|
3月前
|
JSON Java API
解码Spring Boot与JSON的完美融合:提升你的Web开发效率,实战技巧大公开!
【8月更文挑战第29天】Spring Boot作为Java开发的轻量级框架,通过`jackson`库提供了强大的JSON处理功能,简化了Web服务和数据交互的实现。本文通过代码示例介绍如何在Spring Boot中进行JSON序列化和反序列化操作,并展示了处理复杂JSON数据及创建RESTful API的方法,帮助开发者提高效率和应用性能。
141 0
|
3月前
|
JSON Java API
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
|
3月前
|
网络协议 NoSQL 网络安全
【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)
【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)