簡體   English   中英

使用 React 處理身份驗證的最佳方法是什么?

[英]What's the best way to handle authentication with React?

我有一個ProtectedRoute組件:

import React, { useState, useEffect, useContext } from 'react';
import CreateRecipe from "./components/CreateRecipe";
import Login from "./components/Login";
import Register from "./components/Register";
import UserContext from './contexts/UserContext';
import Homepage from './components/Homepage';
import LandingPage from './components/LandingPage';
import EditRecipe from './components/EditRecipe';
import SearchPage from './components/SearchPage';
import ViewRecipe from './components/ViewRecipe';
import { BrowserRouter, Route, Redirect } from 'react-router-dom';
import axios from 'axios';


/**
 * Used for Routes that cannot be accessed without authentication
 */
function ProtectedRoute({ component: Component, ...rest }) {
  const [authCheck, setAuthCheck] = useState({ isAuth: false, loading: true });
  const { auth } = useContext(UserContext.context);

  //async call to check authentication status
  useEffect(() => {
    axios.get('/authUser').then(res => {
      setAuthCheck({ isAuth: res.data.isAuth, loading: false });
    });
  }, []);

  return (

    <Route {...rest} render={(props) =>
      (!authCheck.loading) ? (authCheck.isAuth || auth) ? (<Component {...props} />) : (<Redirect to={{
        pathname: "/login",
        state: { from: props.location },
      }} />)
        : (<div>loading</div>)
    } />
  );

}

function App() {

  return (
    <div>
      <BrowserRouter>
        <UserContext>
          <ProtectedRoute component={Homepage} path="/:username/home" />
          <ProtectedRoute path='/:username/edit/:id' component={EditRecipe} />
          <ProtectedRoute path='/:username/create' component={CreateRecipe} />
          <ProtectedRoute path='/:username/search/:q' component={SearchPage} />
          <ProtectedRoute path='/:username/view/:id' component={ViewRecipe} />
          <Route path='/login' component={Login} />
        </UserContext>
        <Route path='/register' component={Register} />
        <Route exact path="/" component={LandingPage} />
      </BrowserRouter>
    </div>
  );
}

export default App;

我發現 useEffect 鈎子在組件渲染之前就觸發了。 這會導致authCheck.isAuth永久為假,從而阻止用戶登錄。為了解決這個問題,我讓我的登錄組件更新了上下文的身份驗證 state。

我將如何解決 useEffect 問題? 另外,有沒有更好的方法在客戶端設置身份驗證?

.then()重構為async await 它應該正確更新isAuth state,然后您可以刪除auth上下文。

const getAuthUser = async() => {
  try {
    const res = await axios.get('/authUser');
    setAuthCheck({ isAuth: res.data.isAuth, loading: false });
  } catch (e) {
    // handle the error
  } 
};

//async call to check authentication status
useEffect(() => {
  getAuthUser();
}, []);


return (

  <Route {...rest} render={(props) =>
    !authCheck.loading ? authCheck.isAuth ? (<Component {...props} />) : 
    (<Redirect to={{
      pathname: "/login",
      state: { from: props.location },
    }} />)
    : (<div>loading</div>)
   />
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM