我开始使用django-rest框架作为后端,为角度2单页面应用程序开发认证系统。我也想要有某种"记住我"将使用户登录一段时间的功能。
从我到目前为止所读到的,似乎这种Angular 2 SPA / REST API的最佳身份验证方法是使用jwt(json web token)。对于jwt身份验证,我查看了django-rest-framework-jwt(https://github.com/GetBlimp/django-rest-framework-jwt)。
我看到的问题是令牌需要具有较短的生命周期(几分钟到几个小时......),以便在令牌被盗时最大限度地减少安全问题。现在需要经常刷新令牌以避免用户在使用应用程序时断开连接。在这种情况下,记住我"由于令牌的使用寿命很短,因此功能性存在问题。
我想到了一个解决方案,涉及第二个令牌,用作刷新令牌。它将是不透明的,具有更长的寿命并且将包含特定于用户的信息(IP地址或类似的东西),以便如果它被盗,则特定于用户的信息将使该刷新令牌无效。
所以这是我的问题:
1-我想知道它们是否是解决此问题的现有解决方案。对于任何安全/身份验证问题,我更愿意依赖经过良好测试的解决方案来避免让我的API受到损害 2-基于特定用户信息的刷新令牌是一个好主意吗? 3-任何其他想法如何实现我想要的东西?
答案 0 :(得分:3)
根据您的情况,您确实需要一种方法来存储已发行的令牌。
我总是使用管理身份验证的OAuth2.0服务器设置并返回令牌,OAuth设置使用数据库来管理所有内容,因此它易于管理和撤销令牌。
数据库模式就像这个http://imgur.com/a/oRbP2一样,只使用JWT而没有对已发布的令牌进行长期过期管理,你就会遇到无法轻易撤销的安全问题。
我建议不要在JWT中包含任何密码这样的东西,并要求他们改变它,如果他们在任何地方使用该密码,那么他们将不得不在任何地方改变它。
从评论中更新
会话身份验证使用session_id,其中大部分时间都存储在Cookie中,并附加到每个传出请求。这是有状态的。它只不过是一个唯一的标识符,它将服务器在内存/数据库中拥有的用户帐户关联起来。例如,在扩展基础架构时运行多个服务器/实例时,这可能会遇到问题。
令牌身份验证服务器上没有持久会话,因此这意味着它是无状态的。它通常使用标题Authorization:Bearer REPLACE-WITH-TOKEN。这意味着此令牌可以传递到多个不同的服务器/实例,因为身份验证不限于您启动身份验证的服务器。这有助于扩展您的基础架构。代币也可以传递给其他客户。
RESTful API是无状态的,因此服务器上不能存储会话状态。相反,它必须完全由客户端处理,以便使用令牌身份验证。
当我尝试将JWT用于需要比JWT设计更多的应用程序时,我遇到了确切的问题。 OAuth2.0有更多的选项,我认为这些选项是以最安全的方式满足您的需求所必需的,甚至是您将来可能会发现非常有用的功能,因为您的应用程序可能会增长并需要更多功能来进行身份验证。