使 JSON Web 令牌无效 [英] Invalidating JSON Web Tokens

查看:34
本文介绍了使 JSON Web 令牌无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我正在处理的新 node.js 项目,我正在考虑从基于 cookie 的会话方法切换(我的意思是,将 id 存储到包含用户会话的键值存储中用户的浏览器)转换为使用 JSON Web 令牌 (jwt) 的基于令牌的会话方法(无键值存储).

该项目是一个利用 socket.io 的游戏 - 在单个会话(web 和 socket.io)中将有多个通信渠道的场景中,具有基于令牌的会话将非常有用

如何使用 jwt 方法从服务器提供令牌/会话失效?

我还想了解使用这种范式应该注意哪些常见(或不常见)的陷阱/攻击.例如,如果这种范式容易受到与基于会话存储/cookie 的方法相同/不同类型的攻击.<​​/p>

所以,假设我有以下内容(改编自 this这个):

会话存储登录:

app.get('/login', function(request, response) {var user = {username: request.body.username, password: request.body.password };//以某种方式验证验证(用户,功能(isValid,配置文件){//创建会话令牌var token= createSessionToken();//添加到键值数据库KeyValueStore.add({token: {userid: profile.id, expiresInMinutes: 60}});//客户端应将此会话令牌保存在 cookie 中response.json({sessionToken: token});});}

基于令牌的登录:

var jwt = require('jsonwebtoken');app.get('/login', function(request, response) {var user = {username: request.body.username, password: request.body.password };//以某种方式验证验证(用户,功能(isValid,配置文件){var token = jwt.sign(profile, '我的超级秘密', {expiresInMinutes: 60});response.json({token: token});});}

--

会话存储方法的注销(或失效)将需要更新 KeyValueStore具有指定令牌的数据库.

在基于令牌的方法中似乎不存在这种机制,因为令牌本身将包含通常存在于键值存储中的信息.

解决方案

我也一直在研究这个问题,虽然下面的想法都不是完整的解决方案,但它们可能会帮助其他人排除想法,或提供进一步的想法.

1) 只需从客户端移除令牌

显然,这对服务器端安全没有任何作用,但它确实通过删除存在的令牌来阻止攻击者(即,他们必须在注销之前窃取令牌).

2) 创建令牌阻止列表

您可以将无效令牌存储到其初始到期日期,并将它们与传入请求进行比较.不过,这似乎否定了首先完全基于令牌的原因,因为您需要为每个请求访问数据库.不过,存储大小可能会更低,因为您只需要存储注销和登录之间的令牌.到期时间(这是一种直觉,绝对取决于上下文).

3) 保持令牌到期时间短并经常轮换它们

如果您将令牌到期时间保持在足够短的时间间隔内,并让正在运行的客户端在必要时进行跟踪和请求更新,那么第 1 项将有效地用作完整的注销系统.这种方法的问题在于,它无法在客户端代码关闭之间保持用户登录(取决于您设置的到期间隔时间).

应急计划

如果发生紧急情况,或者用户令牌被泄露,您可以做的一件事是允许用户使用他们的登录凭据更改底层用户查找 ID.这将使所有关联的令牌无效,因为将无法再找到关联的用户.

我还想指出,在令牌中包含上次登录日期是个好主意,这样您就可以在一段时间后强制重新登录.

就使用令牌攻击的异同而言,这篇文章解决了这个问题:https://github.com/dentarg/blog/blob/master/_posts/2014-01-07-angularjs-authentication-with-cookies-vs-token.markdown

For a new node.js project I'm working on, I'm thinking about switching over from a cookie based session approach (by this, I mean, storing an id to a key-value store containing user sessions in a user's browser) to a token-based session approach (no key-value store) using JSON Web Tokens (jwt).

The project is a game that utilizes socket.io - having a token-based session would be useful in such a scenario where there will be multiple communication channels in a single session (web and socket.io)

How would one provide token/session invalidation from the server using the jwt Approach?

I also wanted to understand what common (or uncommon) pitfalls/attacks I should look out for with this sort of paradigm. For example, if this paradigm is vulnerable to the same/different kinds of attacks as the session store/cookie-based approach.

So, say I have the following (adapted from this and this):

Session Store Login:

app.get('/login', function(request, response) {
    var user = {username: request.body.username, password: request.body.password };
    // Validate somehow
    validate(user, function(isValid, profile) {
        // Create session token
        var token= createSessionToken();

        // Add to a key-value database
        KeyValueStore.add({token: {userid: profile.id, expiresInMinutes: 60}});

        // The client should save this session token in a cookie
        response.json({sessionToken: token});
    });
}

Token-Based Login:

var jwt = require('jsonwebtoken');
app.get('/login', function(request, response) {
    var user = {username: request.body.username, password: request.body.password };
    // Validate somehow
    validate(user, function(isValid, profile) {
        var token = jwt.sign(profile, 'My Super Secret', {expiresInMinutes: 60});
        response.json({token: token});
    });
}

--

A logout (or invalidate) for the Session Store approach would require an update to the KeyValueStore database with the specified token.

It seems like such a mechanism would not exist in the token-based approach since the token itself would contain the info that would normally exist in the key-value store.

解决方案

I too have been researching this question, and while none of the ideas below are complete solutions, they might help others rule out ideas, or provide further ones.

1) Simply remove the token from the client

Obviously this does nothing for server side security, but it does stop an attacker by removing the token from existence (ie. they would have to have stolen the token prior to logout).

2) Create a token blocklist

You could store the invalid tokens until their initial expiry date, and compare them against incoming requests. This seems to negate the reason for going fully token based in the first place though, as you would need to touch the database for every request. The storage size would likely be lower though, as you would only need to store tokens that were between logout & expiry time (this is a gut feeling, and is definitely dependent on context).

3) Just keep token expiry times short and rotate them often

If you keep the token expiry times at short enough intervals, and have the running client keep track and request updates when necessary, number 1 would effectively work as a complete logout system. The problem with this method, is that it makes it impossible to keep the user logged in between closes of the client code (depending on how long you make the expiry interval).

Contingency Plans

If there ever was an emergency, or a user token was compromised, one thing you could do is allow the user to change an underlying user lookup ID with their login credentials. This would render all associated tokens invalid, as the associated user would no longer be able to be found.

I also wanted to note that it is a good idea to include the last login date with the token, so that you are able to enforce a relogin after some distant period of time.

In terms of similarities/differences with regards to attacks using tokens, this post addresses the question: https://github.com/dentarg/blog/blob/master/_posts/2014-01-07-angularjs-authentication-with-cookies-vs-token.markdown

这篇关于使 JSON Web 令牌无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆