【问题标题】:Is this a sufficiently secure token authentication system made from scratch?这是一个从头开始制作的足够安全的令牌认证系统吗?
【发布时间】:2014-05-31 21:56:29
【问题描述】:

以下是身份验证流程的细分:

  • 用户注册(电子邮件、密码)
  • 用户登录
  • 如果他们的登录有效,则会在服务器端生成一个令牌,代码如下:

    require('crypto').randomBytes(48, function(ex, buf) {
        var token = buf.toString('hex');
        // generates a token, such as....
        //  9b50ea46e80804bfe2ae01d0d1bb099c26887a65c92f61e47677c28ed40dbd4ef4c14f0dc58688ab4ec0df6b766ec90f
    });
    
  • 该令牌返回到客户端,并保存为 cookie

  • 他们登录的用户IP地址与令牌一起存储到数据库中
  • 该令牌存储在数据库中散列,代码如下:

    var salt = bcrypt.genSaltSync(10);
    bcrypt.hash(token, salt, null, function(err, hash) {
        token = hash;
        token.save();
        // salts and hashes a token and saves that hashed token to the database
        // resulting hashed token will look like...
        // $2a$10$rGjMO6bWb/R4/yAAEV8Nx.7Fr6bS.AmMS0vRYB7p5umTpfpjMOfAC
    });
    
  • 在从客户端到服务器的所有未来请求中,“auth_token”标头会自动附加到所有类型的所有请求中,其中包含之前提供给客户端的未散列令牌,该令牌已保存到 cookie

  • 当请求进入服务器时,它会检查是否附加了“auth_token”标头
  • 如果“auth_token”标头不存在,它会拒绝他们从 API 获取数据的请求
  • 如果“auth_token”标头确实存在,它...
    • 检查令牌是否有效(通过对数据库中的令牌执行bcrypt.compare 直到找到匹配项来检查令牌是否存在于数据库中)并且是否属于正在与应用程序交互的当前用户(发送请求与附加到数据库中该令牌的用户 ID 匹配)
    • 检查请求数据的 IP 地址是否与数据库中附加到该令牌的 IP 地址匹配
    • 检查令牌是否已过期(在服务器端,而不是客户端 cookie)
  • 如果上述所有测试都通过,它会为用户提供他们正在寻找的数据...如果它没有通过任何测试,它会给他们一个 403 禁止。

这是我出于学习目的从头开始制作的第一个令牌认证系统。

欢迎提出想法/批评/提问!如果我错过了解释此设置的任何关键部分,请尽管问,我会澄清。

我可以看到有人能够滥用它的唯一方法是:

  • 访问某人的计算机
  • 从他们的 cookie 中获取他们的令牌
  • 在令牌过期前的时间内向 API 发送请求,欺骗用户 IP,使用他们的令牌
  • 已授予数据

但为了做到这一点,他们基本上必须访问那个人的计算机才能获取 cookie,如果他们可以访问那个人的计算机,他们基本上已经可以无限制地访问数据仍然存在,因为很可能该人仍在登录网站和/或该人的密码和用户名自动填写在网站上,等等。

【问题讨论】:

  • 那是......正是我们不希望在 SO 上出现的响应类型。
  • 无论如何,为什么只使用现有的cookie认证机制?这看起来唯一要添加的是一些额外的“IP验证”。
  • 出于了解这些系统如何工作的目的。在应用投入生产之前,我将使用 Passport.js。
  • 这种设置不会有会话——后端只是一个分配数据的 API,没有持久连接,只有请求和响应。需要在每个请求上检查身份验证。
  • 另外,我编辑了帖子以更好地解释“可疑”部分。

标签: node.js security access-token bcrypt


【解决方案1】:

我突然想到了两件事:

  • 永远不要在实际代码中使用同步方法。 (genSaltSync) 加密方法的计算成本很高;在 JS 线程上执行它们是灾难的根源。极少数并发登录尝试会使您的服务器停止运行。

  • 您将用户的 IP 地址视为常量,但这不是一个有效的断言。在 DHCP、频繁更换网络的移动设备、VPN 和代理服务器之间,您无法知道用户的下一个请求是否来自同一个 IP。

    随机拒绝访问的用户所带来的支持噩梦是(IMO)不值得投机的安全收益。只要您正确配置了 SSL 并设置了 cookie Secure and HttpOnly,令牌被盗的风险就很小。

【讨论】:

  • 所以你是说我的设置足够安全,但可能跟踪 IP 是多余的,所以我应该删除它?
  • 如果令牌 cookie 设置正确(SecureHttpOnly),所有 API 请求都通过 https 进行,请注意CSRF,是的。 IP 地址位当然不会降低 安全性,但我认为它也不会增加安全性。它肯定会降低用户的便利性。我会删除它。
  • 我能看到的唯一缺失的部分是防止 CSRF 攻击...我使用 AngularJS 作为我的前端,我会做一些研究,我猜想如何使用 CSRF -保护我的网站。另外你有什么建议可以替代genSaltSync
  • 如果您使用的是this,它似乎有一个异步版本genSalt(n, cb)
猜你喜欢
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
相关资源
最近更新 更多