如何在前端安全地保持用户身份验证状态,或者有可能吗?

时间:2019-01-17 14:47:56

标签: angular security authentication browser frontend

我目前正在尝试实施一个简单的身份验证版本。我不想使用JWT或其他东西。登录系统时,用户将向后端发送验证码。然后后端将仅返回true或false来指示认证是否成功。我希望用户在一段时间内处于身份验证状态。如何在不将任何其他请求发送到后端的情况下实现此功能。我知道我可以在Cookie或本地存储或会话存储中存储某些内容,并检查那些位置以获取身份验证信息。但是用户可以访问这些地方并手动更改某些东西,对吗?因此,这是不安全的。可以将用户的身份验证状态仅保留在前端,但是具有一定的安全性吗?谢谢!

1 个答案:

答案 0 :(得分:0)

与通常的看法相反,您可以将状态实际安全地存储在客户端上,用于许多目的。这就是Rails之类的框架在默认情况下所做的工作,如果没有另外设置,则整个用户会话(所有会话数据)都保存在cookie中。但是,这并不简单,也不是您应该自己实现的东西。

确实,客户端上的任何内容都完全由潜在的恶意用户控制。好吧,除非有适当的保护措施。

此操作的关键是消息身份验证和/或加密(请注意,后者不一定表示前者,这是不同的东西)。

您可以在思维上建模,例如服务器向自己发送一条消息(会话状态,它不希望在两个请求之间记住该会话状态),并且服务器希望确保该消息在(1)期间未更改通过客户端传输(消息身份验证),以及(2)必要时保密(加密)。

要使其正常工作,发送者和接收者都需要有一个共享机密。由于在这种情况下发送方和接收方是相同的(服务器),因此仅意味着需要为您的应用程序存储一个机密。例如,在Rails中,这是从SECRET_KEY_BASE派生的。一旦获得此权限,发送到客户端以进行存储的任何内容都可以在必要时进行加密,并且可以生成消息身份验证代码(MAC)以确保上述属性。实际上,您可以具有会话管理代码来使用您的应用程序密码生成HMAC,将其添加到cookie中,然后让您的应用程序检查MAC以确保cookie未被篡改。如果还需要加密(客户端上存储的状态的安全性),则可能希望选择一种经过身份验证的加密方式(例如AES-GCM),该加密方式可以一次性提供两个属性。

尽管有一个小问题。假设您有一个已加密,认证并存储在客户端上的会话状态。会话状态包括用户的角色。您有一个授予管理员权限的用户。您的用户足够聪明,并保存其cookie以便以后使用。然后,您改变主意,并撤消该用户的admin。如果他发送 did 具有管理员身份的旧Cookie,则不会阻止他成为管理员。这称为重放攻击,如果应用程序中存在问题,则必须手动实施保护。

也可以说您的两个应用程序出于任何原因使用相同的秘密(通常是一个坏主意,但无论如何)。来自一个服务器的加密cookie可能会在另一个服务器中使用,如果处理不当,可能会造成严重破坏或导致漏洞。

现在所有讨论都面临潜在挑战,请注意,这正是JWT为您(使用HMAC)解决的问题,或者是JWE为加密案例解决的问题。除非只是学习这些知识,否则请仅使用标准的JWT / JWE实现,因为要正确地实现这些知识并不容易,而且实现细节也很重要。