【问题标题】:Having one backend manage authentication for a webapp and react native app让一个后端管理 web 应用程序的身份验证并响应本机应用程序
【发布时间】:2021-07-13 05:38:44
【问题描述】:

我打算制作一个包含两个部分的应用程序:

  1. React 原生移动应用
  2. 桌面用户的浏览器网络应用

我正在尝试计划如何为此管理后端身份验证(Node.js、passport.js)。理想情况下,无论哪种类型的客户端,我都可以让一个后端管理它。

假设我将只拥有谷歌身份验证(为简单起见)。我不需要点击 googles API 获取任何信息(如个人资料、联系人等),我只希望他们使用 google 帐户登录。到目前为止,我的理解是有两种主要方式(特别是因为我使用的是 passport.js)。

  1. 基于 jwt 的方法
  2. 基于会话的方法

对于任何一种方法,当涉及到 react native 应用程序时,我的问题就会出现。由于我无法使用HttpOnly cookie,我不确定如何安全地存储数据。例如

  1. 在 jwt 方法中,如果服务器管理访问令牌和刷新令牌,则 react 本地客户端可以将它们存储在同一位置,例如 https://github.com/mcodex/react-native-sensitive-info。这意味着刷新令牌与访问令牌一样容易受到影响,这会破坏刷新令牌的意义,因此不妨让访问令牌长期存在。

  2. 在基于会话的方法中,react native 可以将会话 id 存储在某个位置(如上面的 react-native-sensitive-info),并且会出现同样的问题

我目前对应该做什么的想法:

似乎没有办法解决在 react-native 中存储信息的安全问题,所以到目前为止,我觉得我只是要遵循 JWT 方法,并将访问 + 刷新令牌存储在 react-native-敏感信息。但是,这确实意味着当用户代理移动时,登录端点将在请求正文中返回访问 + 刷新令牌。当用户代理是 web 时,我们应该能够设置一个 httponly cookie。我唯一能想到的是,如果有一个恶意请求屏蔽了用户代理(这可能吗?),然后可以在正文中接收访问 + 刷新令牌,并且可以用它做任何事情。

抛开性能

基于会话的存储方法总体上看起来要简单得多。是的,它确实将状态存储在后端,但是如果我们使用 JWT 方法,无论如何我们都必须在后端的某个地方存储用户刷新令牌(如果有需要使用户刷新令牌无效的情况,例如在注销或损坏预防时) )。

这样,假设我们有一个会话表,当用户注销时,或者如果我们想要使会话无效,我们所要做的就是从该表中删除行。在 JWT 方法中,如果我们想使刷新令牌无效,我们必须有一个阻止列表表(它只会不断增长,因为刷新令牌不应该过期,但我想它们可以在很长一段时间后被删除时间)。但是,如果您有很多用户,则会话表可能会变大,这可能会导致性能问题(但您可能会丢弃超过一定年龄的会话)

/旁观

问题:

  • 我注意到移动应用程序从未要求我使用 OAuth 重新登录。这是否意味着他们在访问令牌过期时不断使用刷新令牌?如果没有明确的方法以安全的方式将其存储在移动设备中,那么它们是否只有超持久的访问令牌?

  • 所有这些想法都是多余的吗?将一个超级持久的访问令牌存储在本机反应中并一直使用它是否可以?那么当用户按下“注销”时,我们可以从本地存储中删除它吗?

  • 像 auth0 这样的第三方身份验证系统会为我管理所有这些吗?

【问题讨论】:

    标签: node.js react-native authentication jwt passport.js


    【解决方案1】:

    我会尝试在不同类型的应用中分享我的经验,这样事情可能会更清楚。

    认证方式

    • 在大多数移动应用程序(带有网络应用程序)上,我在移动端使用了长期访问令牌,大多数应用程序不需要用户在每次打开应用程序时登录。通常我们将令牌存储在安全存储中。

    • 在某些情况下,我使用内存数据库 (Redis) 来使用户的会话非常快,并且您不需要在每次请求时查询主数据库(这用于高可用性系统,它可能对于大多数用例来说都是矫枉过正)

    • 一些非常具体的解决方案可能需要更高的安全性,这取决于您的产品(如银行和交易应用程序或保留敏感数据的应用程序)在这些情况下,我建议您在用户每次关闭应用程序时登录用户或长时间保持不活动状态。 (这种解决方案通常依赖于指纹/faceId 库)

    我对这个问题的个人意见是使用 jwt,如果您需要更改后端并且有更明确的模式要遵循,那么在服务器端很容易维护,但这是我的意见,如果您有高需求或一些具体用例可能会改变。

    存储

    谈到存储选项,有一些很好的建议可以在 react native 文档中以安全的方式保存令牌等数据,我曾经使用过的一个不错的选择是:

    https://github.com/emeraldsanto/react-native-encrypted-storage

    但您可以在这里看到更多选项和优势:

    https://reactnative.dev/docs/security#secure-storage

    第三方库

    如果您的项目有预算并且没有对身份验证过程进行大量自定义,它们通常会帮助您提供基础知识,通常如果它是一个全新的项目(在后端和前端),它们运行良好。 他们中的大多数会为你处理大部分障碍,比如代币翻新,但你应该注意这种方法的价格可扩展性

    祝你的项目成功。

    【讨论】:

    • 感谢您的深入回复!是的,我肯定会学习一种 JWT 方法,它具有更持久的移动令牌(一小时访问令牌,多个月刷新令牌),以及一种使刷新令牌无效的方法(需要存储一个无效刷新令牌表,并添加它们在用户退出时)
    • 是的,失效通常是这样的,你也可以在令牌时间到期时清空你的表,这样你就不会浪费资源。如果你有很多用户或者你的基础增长很快,你可以使用 Redis 的副本数据库来保持性能,只要确保将数据库整合到某个地方,因为 Redis 是一个内存数据库。
    猜你喜欢
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 2017-07-30
    • 2017-02-05
    • 2018-08-11
    • 2012-09-09
    • 2017-07-28
    • 1970-01-01
    相关资源
    最近更新 更多