【问题标题】:React-Firebase routing and authentication approachReact-Firebase 路由和身份验证方法
【发布时间】:2021-12-31 21:58:47
【问题描述】:

我想学习firebase路由认证的正确方法,我的意思是:

function App() {
  const auth = getAuth();

  if (!auth) {
    <Spinner />;
  }

  return (
    <>
      {auth && (
        <Router>
          <Routes>
            <Route path='/' element={<PrivateRoute />}>
              <Route index element={<Explore />} />
              <Route path='/offer' element={<Offers />} />
              <Route path='/profile' element={<Profile />} />
            </Route>
            <Route path='/sign-in' element={<SignIn />} />
            <Route path='/sign-up' element={<SignUp />} />
            <Route path='/forgot-password' element={<ForgotPassword />} />
          </Routes>
          <Navbar />
        </Router>
      )}

我有这个代码块,起初我以为我应该得到一个使用 onAuthStateChangeduseAuth 钩子,但我意识到这个 auth 来自 getAuth 的变量的工作方式是一样的,那么为什么不使用它来代替钩子呢?

而我的 PrivateRoute 看起来像这样:

function PrivateRoute() {
  const currentUser = getAuth().currentUser;

  return currentUser ? <Outlet /> : <Navigate to='/sign-in' />;
}

问题是一旦应用挂载,由于没有应用级状态,它保持不变。

然后,如果我尝试注销并将一些逻辑放入路由中,例如如果用户存在,则不允许路由注册或登录,它不起作用。

如果我使用 redux 或 context API,我会在我登录、注销、注册时调度,但没有它们处理这种路由的正确设置是什么?

【问题讨论】:

    标签: javascript reactjs firebase authentication frontend


    【解决方案1】:

    一段时间后,我只是想出了如何做我需要做的事情,所以我在这里发布,以防万一有人也遇到这个问题并寻求帮助。

    如果你不使用 redux 或 context api 并且仍然想实现这种功能,我是这样做的:

    那么我需要做什么?我想通过 firebase 进行身份验证,您需要做的 - 至少我发现 - 实施 APP/LEVEL/STATE 以检查用户是否登录并更新应用级别渲染,即呈现整个应用程序并相应地强制执行行为。

    所以:

    function App() {
      const [user, setUser] = useState(null);
      const [isLoading, setIsLoading] = useState(true);
    
      useEffect(() => {
        const unsubscribe = onAuthStateChanged(auth, (user) => {
          setIsLoading(true);
    
          if (user) {
            setUser(user);
          } else {
            setUser(null);
          }
    
          setIsLoading(false);
        });
    
        return unsubscribe;
      }, []);
    
      if (isLoading) return <Spinner />;
    
      return (
        <>
          <Router>
            <Routes>
              <Route path='/' element={<PrivateRoute user={user} />}>
                <Route index element={<Explore />} />
                <Route path='/offers' element={<Offers />} />
                <Route path='/profile' element={<Profile />} />
                <Route path='/create-listing' element={<CreateListing />} />
                <Route path='/category/:categoryName' element={<Category />} />
              </Route>
              <Route
                path='/sign-in'
                element={!user ? <SignIn /> : <Navigate to='/' />}
              />
              <Route
                path='/sign-up'
                element={!user ? <SignUp /> : <Navigate to='/' />}
              />
              <Route
                path='/forgot-password'
                element={!user ? <ForgotPassword /> : <Navigate to='/' />}
              />
            </Routes>
            <Navbar />
          </Router>
    
          <ToastContainer autoClose={1000} />
        </>
      );
    }
    
    export default App;
    

    这里,基本上在组件挂载后,我们希望 useEffect 只执行一次,并设置监听器以更改身份验证状态,每当身份验证状态发生更改(如登录或注销)时,onAuthStateChanged 的​​代码块就会运行以及何时运行,每次它设置用户是否有用户时,都会重新渲染 App 本身的组件,并在路由下方相应地工作。如果你像我一样有一条私有路由,你可以将用户作为道具传递,那么:

    import { Navigate, Outlet } from 'react-router-dom';
    
    function PrivateRoute({ user }) {
      return user ? <Outlet /> : <Navigate to='/sign-in' />;
    }
    
    export default PrivateRoute;
    

    【讨论】:

      猜你喜欢
      • 2016-12-11
      • 2017-09-24
      • 2020-06-11
      • 1970-01-01
      • 2021-12-20
      • 2021-11-07
      • 2017-07-12
      • 1970-01-01
      • 2018-02-04
      相关资源
      最近更新 更多