Reactjs Firebase身份验证状态在客户端上保持,但在硬刷新时不保持
我正在构建一个同构的React应用程序,它使用Express来处理服务器请求 在客户端运行捆绑的React应用程序时,我的Firebase登录流运行良好:Reactjs Firebase身份验证状态在客户端上保持,但在硬刷新时不保持,reactjs,firebase,firebase-security,isomorphic-javascript,firebase-authentication,Reactjs,Firebase,Firebase Security,Isomorphic Javascript,Firebase Authentication,我正在构建一个同构的React应用程序,它使用Express来处理服务器请求 在客户端运行捆绑的React应用程序时,我的Firebase登录流运行良好: 我使用Firebase的电子邮件/密码选项登录 身份验证后,ref.getAuth()成功返回用户的身份验证对象 在我的应用程序客户端(通过react路由器)导航时,对ref.getAuth()的后续调用也会返回一个成功的auth对象 但是,即使在成功登录客户端之后,硬刷新(来自服务器)也不会持续。在服务器上下文中使用相同的React组件
- 我使用Firebase的电子邮件/密码选项登录
- 身份验证后,
成功返回用户的身份验证对象ref.getAuth()
- 在我的应用程序客户端(通过react路由器)导航时,对
的后续调用也会返回一个成功的auth对象ref.getAuth()
ref.getAuth()
返回null
我是否遗漏了一个步骤,使其在服务器上的工作方式与在客户端上的工作方式相同(用例是站点的硬刷新)?如果您在服务器上连接到Firebase,作为同构/通用渲染的一部分(我假设您是),Firebase无法知道是哪个用户向您的服务器发起了请求,然后在客户端向Firebase发出了请求,用户的cookie可以发送到Firebase,但在服务器上发起请求的是您的服务器,而不是客户端,因此与任何给定用户都没有关联 我的第一个想法是,为了从服务器发送身份验证,您需要在自己的服务器上进行某种登录;一旦您(通过Firebase或其他方式)验证了用户是他们所说的用户,您就可以(安全地)在用户会话中保存并发送回客户端。然后,在客户端和每个服务器请求上,在使用
React.render*
呈现React应用程序之前,您将使用该用户的令牌调用authWithCustomToken()
然而,需要注意的一点是,对Firebase数据库的身份验证是全局的,当您对Firebase ref进行身份验证时(即使在Node.js中),指向同一数据库的每个其他ref都会使用这些凭据进行身份验证;不能使用单独的引用以不同的用户身份登录。因此,如果服务器上的React呈现管道在调用auth回调和呈现应用程序之间执行任何异步操作(例如,如果在呈现之前使用类似的方式或执行其他奇特的异步数据加载),通过Firebase身份验证的用户在您呈现应用程序时可能已更改。但是,如果渲染管道是完全同步的,则应该可以使用此策略(getAuth()
可以帮助确保在渲染之前具有正确的身份验证)
除此之外,我认为最直接的解决方案是:
authWithPassword
回调的内容),并将其存储在会话中admin
声明设置为true
:此方法将授予服务器对整个Firebase数据库的完全读写访问权限。此令牌将正常过期,因此相应地设置过期时间非常重要
使用安全JWT,只允许访问服务器需要接触的数据片段:此方法更复杂,但它是对服务器进行身份验证的最安全的方法,因为它可以防止服务器做任何不应该做的事情,即使它以某种方式受到损害
ref.getAuth()
之类的方法在React应用程序中获取此数据(因为它在服务器上不起作用),以识别UI中的用户这是一个惊人的答案-谢谢!如果我真的在做一些奇特的异步数据获取(使用react transmit),这整件事会失败吗?@Jon第一个解决方案,附带警告,可能会失败,因为你不能依靠Firebase正确实施你的安全规则,因为第二个请求可能会在异步工作完成之前进入并针对数据库重新身份验证。但是,第二种解决方案,即在您自己的服务器上实现一些安全性(例如,确保用户不请求其无权访问的资源),应该仍然有效,你的意思是在我的Express服务器上或多或少地复制我的FB安全规则吗?我想你是对的a)-即使是一个专用的身份验证服务器也可能无法工作b/c你仍然需要同步调用,这可能会变得很危险。对于b)显然可以将上下文作为第二个参数传递(
var ref=new Firebase(url,new Firebase.context());
,它为每个上下文打开一个单独的套接字。我认为c)是clea