我正在构建一个使用Express来处理服务器请求的同构React应用程序 .
在客户端运行捆绑的React应用程序时,我的Firebase登录流程运行良好:
-
我使用Firebase的电子邮件/密码选项登录
-
认证后,
ref.getAuth()
成功返回用户的auth对象 -
在我的应用程序客户端(通过react-router)导航时对
ref.getAuth()
的后续调用也会返回一个成功的auth对象 .
但是,即使在客户端成功登录后,硬刷新(来自服务器)也不会持续存在 . 在服务器上下文中使用相同的React组件, ref.getAuth()
返回null .
我是否错过了在服务器上以与在客户端上工作相同的方式进行此工作的步骤(用例是网站的硬刷新)?
1 回答
如果您可以将Cookie发送到Firebase,但它是您的服务器,而不是客户端,它在服务器上启动请求,因此不与任何给定用户相关联 .
我的第一个想法是,为了从服务器发送身份验证,您需要在自己的服务器上进行某种登录;一旦您验证(使用Firebase或其他方式)用户是他们所声称的用户,您可以generate a token您可以(安全地)保存在用户的会话中并发送回客户端 . 然后,在客户端和每个服务器请求上,在使用
React.render*
渲染React应用程序之前,您将使用该用户的令牌调用authWithCustomToken()
.但需要注意的是,对Firebase数据库的身份验证是全局的 - 当您对Firebase引用进行身份验证时(即使在Node.js中),指向同一数据库的每个其他ref都会使用这些凭据进行身份验证;您无法使用单独的引用以不同用户身份登录 . 因此,如果服务器上的React渲染管道在调用auth回调和呈现应用程序之间进行任何异步操作(例如,如果您使用类似react-async或在渲染之前执行其他奇特的异步数据加载),则经过身份验证的用户在您渲染应用程序时,您的Firebase可能已更改 . 但是,如果您的渲染管道纯粹是同步的,那么您应该能够摆脱这种策略(
getAuth()
可以帮助确保在渲染之前拥有正确的身份验证) .除此之外,我认为最直接的解决方案如下:
通过您自己的服务器验证您的用户,创建secure token并将其传回客户端以进行身份验证 . 将此令牌存储在用户's session so the client can request it and auth with it on the client as necessary. You' ll中还需要生成您自己的auth数据(通常传递给
authWithPassword
的回调的东西)并将其存储在会话中 .对于Firebase的服务器请求,请使用the recommended server authentication schemes之一:
包含服务器逻辑,以确保当前登录的用户只能访问适当的数据 . 由于上述身份验证方法将授予用户可能访问或无权访问的数据访问权限,因此您需要采取自己的步骤来确保用户不要访问.2882128_t .
将您在步骤1中存储在会话中的身份验证数据作为属性传递给React应用程序,而不是依赖于
ref.getAuth()
之类的东西来在您的React应用程序中获取此数据(因为它不能在服务器上运行),在UI中识别用户 .