簡體   English   中英

如何使用 Django 后端保持用戶登錄 React 應用程序

[英]How to keep user logged in in React app with a Django back-end

我有一個非常著名的問題,我認為每個人都至少解決過一次。 即使頁面被刷新,我也想在我的反應應用程序中保持用戶登錄。 我已經閱讀了有關如何做到這一點的所有相關問題和文章,但不幸的是我一無所獲。 在我的 ProtectedComponent 我有以下代碼:

const ProtectedRoute = ({ notLoggedInPath }) => {
  
  const isLoggedIn = useSelector((state) => state.auth.isLoggedIn);

  return (
    <Fragment>
      {isLoggedIn && <RecorderPage />}
      {!isLoggedIn && <Redirect to={notLoggedInPath} />}
    </Fragment>
  );
};

如您所見,我在我的 auth reducer 的 initialState 中實現了一個名為 isLoggedIn 的變量,如果此變量為真,則受保護的路由將可訪問,否則不可訪問。

在我的登錄組件中,我將從 api 接收到的令牌存儲到 localStorage。 這完全完成了。 但我的主要問題是,當用戶登錄然后導航到受保護的路線時,通過刷新頁面,我的 initialState(isLoggedIn) 消失並更改為 false,從而使用戶注銷。 這在 ReactJS 的培養中是完全自然的。 但是我如何實現一種方式,在啟動我的應用程序時,它會查找對先前接收到的令牌進行身份驗證,如果它尚未過期,它會將用戶導航到刷新應用程序的頁面。 這是由大量網站完成的,所以我知道可以做到。 但我不知道怎么做?

我的登錄組件:

const SignInForm = () => {
  const dispatch = useDispatch();
  const history = useHistory();

  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = () => {
    axios({
      method: 'post',
      url: 'someurl/api/token/',
      data: {
        username: username,
        password: password,
      },
    })
      .then((res) => {
        const token = res.data.access;
        localStorage.setItem('token', token);    
        dispatch(updateUserInStore(token, username));
        dispatch(makeUserLoggedIn());
        history.push('/recorder');
      })
      .catch((err) => {
        console.log(err);
        console.log(err.response);
      });
  };
return (
<some jsx/>
)

值得一提的是,我的母級組件App中也使用了鈎子useEffect。 我的意思是當我的應用程序在 useEffect 中啟動回調時檢查是否可以授權 localStorage 令牌,但由於 js 的異步性質以及 axios 請求,這不是解決方案,因為在收到此 axios 請求的響應之前設置了 initialState .

我的應用組件:

const App = () => {
  const dispatch = useDispatch();
  const history = useHistory();
  const tokenLocalStored = localStorage.getItem('token');

  const checkIfUserCanBeLoggedIn = () => {
    const token = localStorage.getItem('token');
    axios({
      method: 'get',
      url: 'some-url/api/sentence',
      headers: {
        Authorization: `Bearer ${token}`,
      },
    })
      .then((res) => {
        dispatch(makeUserLoggedIn());
      })
      .catch((err) => {
        console.log(err);
        console.log(err.response);
        return false;
      });
  };

  useEffect(() => {
    checkIfUserCanBeLoggedIn();
  });

  return (
     <Some JSX>
)

當頁面重新加載時,在 App.js 上的 useEffect 掛鈎中執行異步邏輯。 在檢查 auth state 時,使用 state 之類的authChecking來顯示加載程序。

const [authChecking, updateAuthChecking] = useState(true)

useEffect(() => {
  asyncFunc
  .then(updateUserObjToStore)
  .finally(() => updateAuthChecking(false))
}, [])

我還在媒體上寫了一篇關於此的文章,如果您有任何疑問,請隨時查看。 https://medium.com/@jmathew1706/configuring-protected-routes-in-react-using-react-router-af3958bfeffd

額外提示:嘗試將此邏輯保留在自定義掛鈎中將確保正確分離關注點。

暫無
暫無

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

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