【问题标题】:How to keep authenticated state on refresh?如何在刷新时保持经过身份验证的状态?
【发布时间】:2021-05-22 04:24:58
【问题描述】:

我正在为我的应用使用 Firebase 身份验证。我使用了来自here 的 useAuth 钩子。与react-router guide 集成关于重定向(Auth)。

SignIn,SignOut 函数按预期工作。但是当我尝试刷新页面时。它再次重定向到/login

我的预期:通过身份验证后重定向到/ 路由。

我尝试在 PrivateRoute.js 中添加此代码

  if (auth.loading) {
    return <div>authenticating...</div>;
  }

所以我可以在不重定向到/login 的情况下刷新页面,但它只在单击log out 按钮时显示authenticating...

这是我的代码:https://codesandbox.io/s/frosty-jennings-j1m1f?file=/src/PrivateRoute.js

我错过了什么?谢谢!

【问题讨论】:

  • 您的代码和框似乎永远在加载/验证,并且使您的问题无法重现。
  • @DrewReese 你可以再次查看
  • 你检查用户太快了。你应该在你的钩子获取用户信息时显示加载组件。
  • @ducmai 怎么等呢?

标签: reactjs firebase react-router react-router-dom


【解决方案1】:

问题

您似乎没有充分呈现“正在验证”的加载状态。

我认为,当初始身份验证检查正在解决时,您没有正确清除 useEffect 中的 useAuth 中的 loading 状态。

解决方案

在启动身份验证检查或操作时设置loading true,并在检查或操作完成时清除。

使用身份验证

function useProvideAuth() {
  const [loading, setLoading] = useState(true); // <-- initial true for initial mount render
  const [user, setUser] = useState(null);

  // Wrap any Firebase methods we want to use making sure ...
  // ... to save the user to state.
  const signin = (email, password) => {
    setLoading(true); // <-- loading true when signing in
    return firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then((response) => {
        setUser(response.user);
        return response.user;
      })
      .finally(() => setLoading(false)); // <-- clear
  };

  const signout = () => {
    setLoading(true); // <-- loading true when signing out
    return firebase
      .auth()
      .signOut()
      .then(() => {
        setUser(false);
      })
      .finally(() => setLoading(false)); // <-- clear
  };

  // Subscribe to user on mount
  // Because this sets state in the callback it will cause any ...
  // ... component that utilizes this hook to re-render with the ...
  // ... latest auth object.
  useEffect(() => {
    const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        setUser(user);
      } else {
        setUser(false);
      }
      setLoading(false); // <-- clear
    });

    // Cleanup subscription on unmount
    return () => unsubscribe();
  }, []);

  // Return the user object and auth methods
  return {
    loading,
    user,
    signin,
    signout
  };
}

照原样检查PrivateRoute中的加载状态

function PrivateRoute({ children, ...rest }) {
  const auth = useAuth();

  if (auth.loading) return "authenticating";

  return (
    <Route
      {...rest}
      render={({ location }) =>
        auth.user ? (
          children
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: location }
            }}
          />
        )
      }
    />
  );
}

演示

【讨论】:

    【解决方案2】:

    试试这个方法,它对我有用:

    const mapStateToProps = state => ({
      ...state
    });
    
    function ConnectedApp() {
         const [auth, profile] = useAuth()
    
         const [isLoggedIn, setIsLoggedIn] = useState(false)
    
         useEffect(() => {
    
           if (auth && auth.uid) {
              setIsLoggedIn(true)
           } else {
              setIsLoggedIn(false)
           }
         }, [auth, profile]);
    
         return (<Router>
           <Redirect to="/app/home"/>
           <div className="App">
           <Switch>
    
            <Route path="/home"><Home/></Route>
            <Route path="/login"><Login styles={currentStyles}/></Route>
            <Route path="/logout"><Logout styles={currentStyles}/></Route>
            <Route path="/signup" render={isLoggedIn
                ? () => <Redirect to="/app/home"/>
                : () => <Signup styles={currentStyles}/>}/>
            <Route path="/profile" render={isLoggedIn
                ? () => <Profile styles={currentStyles}/>
                : () => <Redirect to="/login"/>}/>
    
          </Switch>
        </div>
      </Router>);
        }
    const App = connect(mapStateToProps)(ConnectedApp)
    
    export default App;
    

    【讨论】:

    猜你喜欢
    • 2021-05-26
    • 2013-01-27
    • 1970-01-01
    • 2021-03-04
    • 2019-09-12
    • 2020-09-16
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    相关资源
    最近更新 更多