【问题标题】:Nodejs - Is it necessary to decode an Authentication Token?Nodejs - 是否有必要解码身份验证令牌?
【发布时间】:2013-12-25 15:35:29
【问题描述】:

我在服务器端使用 Node.js 和 Passportjs 的组合,在客户端使用 Emberjs 来开发应用程序。我目前的身份验证策略是使用 Passport-Local 以标准的电子邮件/密码组合对用户进行身份验证,然后挂钩会话创建机制以生成身份验证令牌,将其保存到单独的表中,并传回给用户用于任何进一步受保护的路线。 (在 REST 标头中传递)。

令牌的创建很好,我这样做没有问题,但是如果我需要额外的步骤,我正在努力解决。

目前,我使用随机的node-uuid 传递作为有效负载,并使用用户 UID(另一个 node-uuid)作为秘密来生成带有 node-jwt-simple 的令牌。然后,我将其保存到客户端的 $.cookie 和服务器端的表中,以及创建日期。

显然,node-jwt-simple 中的步骤之一是对令牌进行编码。还提供了解码功能。我的问题是,在进行身份验证检查时是否需要将令牌解码为某种东西,或者只是检查用户的会话 cookie(REST 标头)是否与数据库中的令牌匹配就足够了?我不想费尽心思去生成一个令牌,然后错过一个重要的步骤,但我不知道如何将它解码成任何可以提供任何额外有用安全性的东西。

更新:

我想我昨晚解决了这个问题:

解决方案似乎是使用用户的 UID 作为 JWT 的有效负载,使用静态字符串作为秘密(取自服务器环境变量或类似的东西),然后只将编码的令牌存储在数据库中。将令牌传回客户端进行重新验证,然后当客户端尝试访问受保护的路由时,他们必须将其 UID 与编码的令牌一起传递给服务器,然后对其进行解码,并将解码后的有效负载与 UID 进行比较已经通过了。如果它们匹配,则验证成功,否则令牌被销毁,用户必须重新登录。 通过这样做,在不知道密钥或拥有用户 UID 的情况下,令牌存储实际上变得无用,但使身份验证过程更加安全。

【问题讨论】:

    标签: node.js authentication cookies ember.js jwt


    【解决方案1】:

    如果您不验证令牌,您也可以创建一些其他随机数据用作会话 cookie,只要它是唯一的并且客户端无法猜到。

    但是由于您已经付出了很多努力,您可以在令牌中编码一些有用的东西,告诉您它的有效期,例如exp 字段,因此您不必从数据库中读取。

    我不确定我是否完全理解您的 JWT,但我看到的问题是您需要信息来解码可能不在您手边的令牌。所以你必须在你的数据库中进行搜索。

    我认为使用一些随机会话密钥就足够了,例如以下功能:

    var crypto = require('crypto');
    
    /**
     * Create random bytes and encode base64url.
     * @param {int} [lengthInBytes=40] the size of the raw token in bytes
     *        (will be longer since base64url-encoded)
     * @param {function} callback node-style callback-function;
     *        data-parameter is a string w/ a shortened (no trailing ==)
     *        base64url-encoded string of the generated bytes.
     */
    exports.createRandomToken = function createRandomToken(lengthInBytes, callback) {
        if (typeof lengthInBytes === 'function') {
            callback = lengthInBytes;
            lengthInBytes = 40;
        }
        crypto.randomBytes(lengthInBytes, function (ex, buf) {
            if (ex) {
                callback(ex);
                return;
            }
            callback(null, buf.toString('base64')
                              .replace(/\//g, '_')
                              .replace(/\+/g, '-')
                              .replace(/=/g, ''));
        });
    };
    

    【讨论】:

    • 认为我已经解决了(为什么它对解码很有用):如果我将用户的 UID 编码到令牌中(作为有效负载,在服务器端使用一些秘密但静态的字符串),然后在每个 Auth 请求中将 UID 与 Token 一起传递给服务器,然后服务器可以解码 Token 并根据 UID 检查有效负载。如果它们匹配,则已验证,否则服务器会销毁令牌,您必须再次登录。这可以防止令牌从服务器被盗时被使用,并且只有在客户端的 cookie 被劫持时才会留下安全漏洞,这可以通过 HTTPS 解决。
    【解决方案2】:
    1. 将令牌的过期时间设置得越小越好(5 分钟、30 分钟、月或年)。
    2. 使用刷新令牌获取新令牌并在每次更新旧令牌时更新刷新令牌(毫无疑问,当用户登录时)
    3. 不要在令牌中存储密码、信用卡号和任何机密信息(我确定,你知道的 :))
    4. 存储所有必要的信息以检查权限(或检查 ip,例如)。它适用于 REST API 和水平扩展。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-04
      • 2013-06-28
      • 1970-01-01
      • 2016-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      相关资源
      最近更新 更多