reactjs - Firebase 身份验证状态在客户端上保留,但在硬刷新时不保留

标签 reactjs firebase firebase-security isomorphic-javascript firebase-authentication

我正在构建一个同构 React 应用程序,它使用 Express 来处理服务器请求。

在客户端运行捆绑的 React 应用程序时,我的 Firebase 登录流程运行良好:

  • 我使用 Firebase 的电子邮件/密码选项登录
  • 身份验证后,ref.getAuth()成功返回用户的auth对象
  • 在我的应用客户端(通过 React-router)导航时对 ref.getAuth() 的后续调用也会返回成功的身份验证对象。

但是,即使在客户端成功登录后,硬刷新(来自服务器)也不会持续。在服务器上下文中使用相同的 React 组件,ref.getAuth() 返回 null。

我是否缺少一个步骤,使其在服务器上的工作方式与在客户端上的工作方式相同(用例是网站的硬刷新)?

最佳答案

如果您在同构/通用渲染过程中连接到服务器上的 Firebase(我假设您是这样),则 Firebase 无法知道哪个用户向您的服务器发起了请求,然后又向您的服务器发出了请求Firebase - 在客户端上,用户的 Cookie 可以一起发送到 Firebase,但在服务器上发起请求的是您的服务器,而不是客户端,因此不与任何给定用户关联。

我的第一个想法是,为了从服务器发送身份验证,您需要在自己的服务器上进行某种登录;一旦您验证(使用 Firebase 或其他方式)用户确实是他们所说的人,您就可以 generate a token您可以(安全地)保存在用户 session 中,也可以发送回客户端。然后,在客户端上,每个服务器请求上,在使用 React.render* 渲染 React 应用程序之前,您将调用 authWithCustomToken() 使用该用户的 token 。

但是,需要注意的是,对 Firebase 数据库的身份验证是全局的 - 当您对 Firebase 引用进行身份验证时(即使在 Node.js 中),指向同一数据库的每个其他引用都会使用这些凭据进行身份验证;您无法使用单独的引用以不同的用户身份登录。因此,如果服务器上的 React 渲染管道在调用 auth 回调和渲染应用程序之间执行任何异步操作(例如,如果您使用类似 react-async 的内容或在渲染之前执行其他奇特的异步数据加载),则用户在您渲染应用程序时,针对您的 Firebase 进行的身份验证可能已更改。但是,如果您的渲染管道是纯粹同步的,您应该能够摆脱此策略(getAuth() 可以帮助确保您在渲染之前拥有正确的身份验证)。

除此之外,我认为最直接的解决方案如下:

  1. 通过您自己的服务器对您的用户进行身份验证,创建 secure token并将其传回客户端以进行身份​​验证。将此 token 存储在用户的 session 中,以便客户端可以请求它并根据需要在客户端上使用它进行身份验证。您还需要生成自己的身份验证数据(通常传递给 authWithPassword 回调的内容)并将其存储在 session 中。

  2. 对于向 Firebase 发出的服务器请求,请使用 the recommended server authentication schemes 之一:

    Using a Firebase app secret: All authentication methods can accept a Firebase app secret instead of a JWT token. This will grant the server complete read and write access to the entire Firebase database. This access will never expire unless it is revoked via the App Dashboard.

    Using a secure JWT with the optional admin claim set to true: This method will grant a server complete read and write access to the entire Firebase database. This token will expire normally, so it is important to set the expiration times accordingly.

    Using a secure JWT designed to give access to only the pieces of data a server needs to touch: This method is more complicated, but it is the safest way to authenticate a server as it lets the Security and Firebase Rules prevent the server from doing anything it's not supposed to, even if it becomes compromised in some way.

  3. 包含服务器逻辑以确保当前登录的用户只能访问适当的数据。由于上述身份验证方法将授予对用户可能有权或无权访问的数据的访问权限,因此您需要采取自己的步骤来确保用户不会意外访问他们有权访问的内容。不应该。

  4. 将您在第一步中存储在 session 中的身份验证数据作为属性传递给 React 应用程序,而不是依赖诸如 ref.getAuth() 之类的东西来获取这些数据您的 React 应用程序(因为它无法在服务器上运行),以识别 UI 中的用户。

关于reactjs - Firebase 身份验证状态在客户端上保留,但在硬刷新时不保留,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32027369/

相关文章:

css - :hover and :focus inline style in React doesn't work

javascript - 在渲染中响应返回

ios - 未设置 Firebase iOS SDK + GTM + Analytics 类别

java - 库 com.google.android.gms :play-services-basement is being requested by various other libraries at [[15. 0.1,15.0.1]],但解析为 16.1.0

firebase - 如果密码或用户电子邮件格式不正确,则返回错误消息

ios - Firebase数据库swift的权限被拒绝

javascript - 如何正确使用 Formik 的 setError 方法? ( react 库)

firebase - 使用 Firebase UID 作为二维码标签是否安全?

database - Firebase 如何确保我的数据安全?

javascript - 无法部署到 Heroku,未进行任何更改