Firebase RESTAPI身份验证策略以及如何在客户端应用程序上存储令牌
我正在为本机(移动应用程序)和基于浏览器的应用程序(react等)设置RESTAPI。我正在将Firebase RESTAPI身份验证策略以及如何在客户端应用程序上存储令牌,firebase,firebase-authentication,jwt,passport.js,refresh-token,Firebase,Firebase Authentication,Jwt,Passport.js,Refresh Token,我正在为本机(移动应用程序)和基于浏览器的应用程序(react等)设置RESTAPI。我正在将express.js和passport.js与LocalStrategy和JwtStrategy一起使用 我研究过这个话题,有很多不同的对话或教程。大多数教程只是创建一个访问令牌,从未讨论过如何刷新它。还有很多人只是使用提供者,比如Okta或Auth0。我不想重新发明轮子,但我认为我应该能够创建一个简单的身份验证机制 我现在的过程是这样的, *在登录时创建访问和刷新令牌。将它们作为响应返回。 *客户端存
express.js
和passport.js
与LocalStrategy和JwtStrategy一起使用
我研究过这个话题,有很多不同的对话或教程。大多数教程只是创建一个访问令牌,从未讨论过如何刷新它。还有很多人只是使用提供者,比如Okta
或Auth0
。我不想重新发明轮子,但我认为我应该能够创建一个简单的身份验证机制
我现在的过程是这样的,*在登录时创建访问和刷新令牌。将它们作为响应返回。
*客户端存储它。在react中,我使用
localStorage
存储令牌。*向请求添加
授权:承载头。
*当访问\u令牌
过期时,使用当前的刷新\u令牌
获取新令牌
我正在将刷新令牌存储到服务器上的DB中。因此,用户可以跟踪他们当前的所有会话,或者管理员可以在出现安全问题时调用它们
经过大量研究,我发现在使用localStorage
在浏览器上存储令牌,或者将令牌作为httpOnly
cookies返回的问题上存在很大分歧
当我查看一些流行网站时,我发现Facebook、Github、Youtube、9gag等网站都使用cookies让你登录。他们不发送授权:承载
头。localStorage中主要有关于UI状态的信息。但是,当您删除SID
cookie时,它们都会将您注销。他们是否使用基于会话的身份验证
当您登录到TMDb(电影数据库)时,它会设置两个cookie,分别命名为access\u token
(它只是一个JWT)和会话
。我猜这是一个服务器返回访问令牌和某种“持久性”信息(会话)作为cookie的实现
Firebase(关于这个主题我最喜欢的一个)只将访问和刷新令牌存储到localStorage
。它实际上使用了indexedDB
,但我已经读到,当它不能使用indexedDB时,它会退回到本地存储
但OWASP建议“基于浏览器的应用程序永远不要检索刷新令牌”。我猜这意味着当访问令牌过期时,应该检查授权服务器以查看是否仍有会话在进行,然后检索新的访问令牌。(无声续约)
我看到的唯一例外是Azure门户。它在授权
头中发送承载令牌。它将刷新令牌存储在localStorage
中。许多“安全敏感”的公司使用它来部署/维护他们的应用程序或数据库等
因此,Firebase和Azure Portal是访问/刷新保存到浏览器上localStorage的令牌的示例。TMDb是在httpOnly
cookies中获取令牌的一个示例。Facebook、Youtube等都在使用某种我无法理解的身份验证机制。我想是饼干和会议吧
向本机和基于浏览器的应用程序返回访问和刷新令牌的逻辑和实现非常简单。将它们存储在localStorage中总是感觉这是一个很大的风险。但我不想为web应用程序设置cookie,并为移动应用程序返回JSON响应。我觉得他们应该是一样的。在看过Firebase和Azure Portal这样的例子之后,我并不觉得这有什么不对
但是,即使有很多关于这方面的分歧和文章,这真的安全吗?即使Firebase和Azure Portal是这一策略的好例子,为什么Facebook、9gag、Youtube等网站主要使用cookie(我认为还有会话)进行身份验证
我知道这是一个大话题。我知道可能有很多不同的方法。但我认为我需要一些基础想法来实现简单应用程序的身份验证。您使用了什么?特别是你保持刷新令牌多长时间?当用户在500个新的私有窗口中使用登录并在不注销的情况下关闭它时,您会怎么做?数据库中该用户有500个刷新令牌吗?我返回一个访问令牌(在1小时内到期)和一个刷新令牌(在1周内到期)。当发出请求时,它首先检查访问令牌是否仍然有效。如果超过了它的过期时间,或者如果它将在未来5分钟内过期,我会将刷新令牌发送到请求正文中的/refresh令牌端点。它验证刷新令牌,用新的刷新令牌交换当前的刷新令牌,用刷新令牌更新保存userId的数据库表。生成新的访问令牌并返回访问令牌和刷新令牌。然后客户端将它们存储到本地存储并继续当前请求。关键点是,暂停客户端发出的请求并只调用一次/refresh令牌端点。你可以使用axios拦截器、redux observable(或者简单地说是rxjs)等等。这对我来说是最难的部分。但你可以找到类似方法的例子。您还可以限制用户的刷新令牌计数。例如,当用户登录并在数据库中已经有5个刷新令牌时,您可以删除最旧的更新令牌,并插入新的令牌。我也建议您真正考虑使用传统会话。我告诉你的流程只是试图从头开始重新发明轮子。会话已经解决了很多这样的问题,并且从web应用程序的早期开始就存在。这是一个很好的解释:有很多不同的观点。关于他们有很多起伏。但我建议您采取最简单的方法,只关注您的生产力和其他特性。我被Authenticate困住了