基本身份验证是正确的选择吗?

Is basic authentication the right choice?

我一直在使用 Dropwizard 为我的网络应用程序开发 RESTful 后端。现在,开发前端,我需要登录用户。我一直在使用@Auth 注释,例如:

@POST
public void createEvent(@Auth User user, @FormParam("startTime") @NotNull @Min(0) Long startTime,
                        @FormParam("endTime") @NotNull @Min(0) Long endTime) {
    validateEvent(startTime, endTime);
    eventDAO.insertEvent(new Event(Util.convertMillisToDate(startTime), Util.convertMillisToDate(endTime), user.getName()));
}

以确保用户已登录。一切都很好,但这是使用 http 基本身份验证。结果是我每次要执行操作时都必须将用户名和密码发送到服务器。这就引出了一个问题:我应该如何将密码存储在客户端上?我是否应该在客户端对密码进行哈希处理(也许连同它的盐一起?),这样如果我将它们存储在例如cookie,对于可以访问计算机的人来说,它不是明文吗?我应该一直使用用户访问令牌吗?

在这种情况下,我建议您使用AUTH 2 身份验证系统。

  1. 这里重要的是散列不是加密并且添加到即使存储的 cookie 也可以访问。
  2. 通过使用令牌,您可以让用户使用他们的帐户登录第三方应用程序,从而减轻痛苦。

使用某种会话令牌几乎总是最佳选择。您只需发送一次用户名和密码,然后您将获得一个会话令牌,用于在所有其他请求中识别用户。

这里有很多优点:

  1. 您不需要在客户端上存储密码,只需存储会话令牌。
  2. 如果会话遭到破坏(例如,被恶意客户端破坏),您可以使令牌无效,而不必同时更改密码。
  3. 您可以限制特定令牌的权限。
  4. 您可以让用户为第三方应用程序生成令牌,而无需为这些应用程序提供密码。

第 1-2 点在任何系统中都很好,因为它们通常使会话更安全。当您设计 public API 时,第 2-4 点特别有用,因为您可以使用像 OAuth 2.0 这样的协议来为第三方应用程序提供对您应用程序的全部或部分的安全且可撤销的访问权限,而无需将用户名或密码泄露给该第三方。

正如其他人所说,令牌很棒,因为您可以控制它们,在需要时撤销等。您只应存储令牌客户端。如果将密码存储在服务器 Db 中,则仍应加盐以防 Db 遭到破坏。

只需了解 JWT 与其他不透明令牌和机制之间的区别。 JWTS 将信息直接存储在令牌中并经过签名(尽管未加密),因此您不会存储个人身份信息,而是 user_id 或类似信息。

我写了一篇关于各种令牌类型的安全相关博客 post,使用 Cookie 与本地存储等。 https://www.moesif.com/blog/technical/restful-apis/Authorization-on-RESTful-APIs/

另外,看看https://jwt.io/introduction。它概述了 JWT 的工作原理。 (我与 Auth0 BTW 没有任何关系,但我们将它们用于我们的公司 Moesif)。