如何在反应应用程序中重新加载每个页面时停止 firebase re-auth()?

Posted

技术标签:

【中文标题】如何在反应应用程序中重新加载每个页面时停止 firebase re-auth()?【英文标题】:How to stop firebase re-auth() on every page reload in a react app? 【发布时间】:2020-05-26 02:40:44 【问题描述】:

所以我有这个使用 firebase auth 和 firestore 的很棒的 react 应用程序。 一切正常,除了

每当我在用户已经登录的情况下重新加载页面时...导航栏链接会改变一秒钟。 看起来应用程序会在每个页面重新加载时自动重新登录(重新验证)用户。为什么这样?如何摆脱它?一些相似的代码示例

import React, useState, useEffect from 'react';
import Switch, Route from 'react-router-dom'
import firebase from 'firebase/App'

export const App = () => 
    const [isAuth, setIsAuth] = useState()
    const auth = firebase.auth()

    useEffect(() => 
        auth.onAuthStateChanged(user => 
            if(user) 
                setIsAuth(true)
             else 
                setIsAuth(false)
            
        )
    , [isAuth])

    return(
        <div className="App">
            <Navbar />
            <Switch>
                <Route to="/signIn" component=Login />
                <Route to="/signUp" component=SignUp />
                <Route to="/signOut" component=SignOut />
            </Switch>
        </div>
    )
;

【问题讨论】:

这能回答你的问题吗? How do I keep a user logged into firebase after refresh in React.JS? 不……那是完全不同的事情。 您看到的是预期的行为:当您重新加载页面时,Firebase 将刷新用户的 ID 令牌。另请参阅我今天早些时候的解释:***.com/questions/60149287/…,其中包括检测用户(可能)稍早通过身份验证的技巧,而无需闪光灯。 【参考方案1】:

终于修好了。

发生这种情况的原因是因为 firebase 服务器在每次重新加载页面时都会验证用户,这需要一些时间并导致导航栏中闪烁半秒。

解决方案只需三个简单的步骤

    登录后,将用户作为布尔值存储在本地存储中。

     firebase.auth().onAuthStateChanged(user=>
         if (user) 
             // store the user on local storage
             localStorage.setItem('user', true);
          else 
             // removes the user from local storage on logOut
             localStorage.removeItem('user');
         
     )
    

    从导航栏组件的本地存储中检查用户

     const userLocal = JSON.parse(localStorage.getItem('user'));
     userLocal ? <SignedInLinks/> : <SignedOutLinks/>;
    

    注销时从本地存储中删除用户

【讨论】:

您是如何处理授权令牌过期的情况的?我遇到了类似的问题,并想到了与您相同的解决方案。 Localstorage 仍将包含“用户”,并且当用户实际未经过身份验证时,您将显示签名链接。 @Marlon 如果身份验证令牌过期,这不会以未定义的用户命中onAuthStateChanged 吗?【参考方案2】:

@illiterate.farmer 你几乎是对的。实际上,您应该只在 localStorage 中保存一个标志 isSignedIn=true or false,因为保存完整的 user 对象会使您的应用很容易受到黑客攻击。

任何 javascript 函数都可以访问 localStorage,因此它将向您公开可用于在后端系统中冒充真实用户的令牌。

【讨论】:

【参考方案3】:

我也遇到了这个问题,我认为 Firebase 的预期方法是使用 FirebaseAuthConsumer...providerId 在等待身份验证状态时为空。

比较 this sandbox 与 this one 相比,this sandbox 在登录内容之前呈现“未登录”内容,直到 Firebase 告诉我们用户是否登录。将首次加载时需要按“登录”按钮,然后刷新以测试行为。

【讨论】:

以上是关于如何在反应应用程序中重新加载每个页面时停止 firebase re-auth()?的主要内容,如果未能解决你的问题,请参考以下文章

在 history.push 反应之后如何停止重新加载整个组件

反应:停止映射组件的重新渲染

在Streamlit中使用Python选择任何小部件后如何停止重新加载页面

页面重新加载后如何保持在反应(antd)表中的同一页面

在不使用 UpdatePanel 的情况下单击 RadioButtonList 时如何停止页面重新加载?

嵌套反应路由器组件不会在页面重新加载时加载/渲染?