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

这个项目是一个利用socket的游戏。IO——在一个会话(web和socket.io)中有多个通信通道的情况下,有一个基于令牌的会话会很有用。

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

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

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

会话存储登录:

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

口令登录:

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

--

会话存储方法的注销(或失效)需要更新KeyValueStore 使用指定的令牌创建数据库。

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


当前回答

代币的有效期为1天 每天建立一个黑名单。 将无效/注销令牌放入黑名单

对于令牌验证,首先检查令牌的过期时间,如果令牌没有过期,则检查黑名单。

对于长会话需求,应该有一种机制来延长令牌过期时间。

其他回答

我只是保存令牌到用户表,当用户登录时,我将更新新的令牌,当auth等于用户当前jwt。

我认为这不是最好的解决方案,但对我来说是可行的。

在内存中做一个这样的列表

user_id   revoke_tokens_issued_before
-------------------------------------
123       2018-07-02T15:55:33
567       2018-07-01T12:34:21

如果您的令牌在一周内过期,则清除或忽略更早的记录。同时只保留每个用户的最新记录。 列表的大小取决于您保留令牌的时间以及用户撤销令牌的频率。 仅当表发生变化时才使用db。在应用程序启动时将表加载到内存中。

IAM解决方案,如Keycloak(我曾经工作过)提供令牌撤销端点

令牌撤销端点 /领域/{域名}/协议/ openid-connect /撤销

如果只是想注销用户代理(或用户),也可以调用端点(这将使令牌无效)。同样,在Keycloak的情况下,依赖方只需要调用端点

/realms/{realm-name}/protocol/openid-connect/logout

链接以防万一,如果你想了解更多

另一种选择是为关键的API端点提供一个中间件脚本。 如果管理员使令牌失效,此中间件脚本将检入数据库。 这种解决方案可能适用于不需要立即完全阻止用户访问的情况。

即使从存储中删除令牌,它仍然有效,但只是在短时间内有效,以降低它被恶意使用的可能性。

您可以创建一个拒绝列表,一旦从存储中删除令牌,就可以将令牌添加到该列表中。如果你有一个微服务,所有其他使用这个令牌的服务都必须添加额外的逻辑来检查这个列表。这将集中您的身份验证,因为每个服务器都必须检查一个集中的数据结构。