簡體   English   中英

堅持 React 基於 Cookie 的身份驗證 state

[英]Persist React Cookie-based Authentication state

我正在使用 React-Router 和 Redux 構建身份驗證流程,其中我的后端以 Session Cookie(帶有 Set-Cookie HTTP 標頭)的形式返回 JWT,前端使用它來發出后續請求。 (我沒有使用 localStorage,因為一般建議是更喜歡 Cookie,因為在 XSS 的情況下它有被 JS 讀取的風險)

// my App component
  const { isAuthenticated } = useSelector((state) => state.user);

          <Container>
            {!isAuthenticated ? (
              <LoginForm />
            ) : (
              <Switch>
                <Route exact path="/" component={MessageList} />
                <Route path="/messages" component={MessageList} />
                <Route path="/login" component={LoginForm} />
                <Route path="/message/:id" component={MessageContainer} />
              </Switch>
            )}
          </Container>
// the api requests themselves abstracted
const login = (data) =>
  axios
    .post("auth/login", data, { withCredentials: true })
    .then((response) => response.data);

const fetchItems = (page, token) =>
  axios(`message/list/page/${page}`, {
    withCredentials: true,
  }).then((response) => response.data);
// actions
function handleError(err) {
  return {
    type: "ERROR_OCCURED",
    payload: err,
  };
}

function shouldFetchMessages(state, page) {
  if (!state.message.all.length) {
    return true;
  } else if (state.message.isFetching) {
    return false;
  } else {
    return state.message.all;
  }
}

export let getMessages = (page = 1) => async (dispatch, getState) => {
  let err, response;

  dispatch(requestMessages(page));
  [err, response] = await to(api.fetchItems(page, getState().user.accessToken));
  if (err) {
    return handleError(err);
  }
  return dispatch(receiveMessages(response));
};

export function getMessagesIfNeeded(page) {
  return (dispatch, getState) => {
    if (shouldFetchMessages(getState(), page)) {
      return dispatch(getMessages(page));
    }
  };
}
// reducer
// where would the localStorage isAuthenticated value be synced with the store?
export default (state = defaultState, action) => {
  switch (action.type) {
    // skipped the other reducers for brevity
    case "ERROR_OCCURED":
      return {
        ...state,
        isAuthenticated: false, // this should be saved in the localStorage
      };
    default:
      return state;
  }
};

我需要一個BOOLEAN來保存isAuthenticated的“狀態”,以便我可以顯示適當的組件。

我的主要問題是 Redux state 當然不會在頁面刷新時持續存在。

我想到了一個localStorage變量(或一個新的cookie )。 (包含 JWT 的 Cookie 是httpOnly ,據我所知,JavaScript 無法訪問)。

問題:

  • 這是慣例嗎
  • JWT 過期將如何處理? (如果 HTTP 請求因 401 而失敗,我想我可以將其設置為 false。)
  • localStorage 變量在哪里與 Redux state 同步以避免在我的 Reducers 中產生副作用?

我絕對不是這方面的專家,但在我的應用程序中,每當我設置或刪除 httpOnly JWT cookie 時,我也會設置/刪除一個常規 cookie,其中包含有關用戶是否登錄及其角色的信息。 然后你就可以在客戶端檢查一些東西而不會暴露任何敏感信息。

暫無
暫無

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

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