【发布时间】:2020-09-16 04:17:18
【问题描述】:
我正在使用 React-Router 和 Redux 构建身份验证流程,其中我的后端以会话 Cookie(带有 Set-Cookie HTTP 标头)的形式返回 JWT,前端使用该 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 状态当然不会在页面刷新时保持不变。
我想有一个localStorage 变量,(或一个新的cookie)。 (包含 JWT 的 Cookie 是httpOnly,据我了解,JavaScript 无法访问)。
问题:
- 这是一种既定做法
- 如何处理 JWT 过期? (我想如果 HTTP 请求失败并返回 401,我可以将其设置为 false。)
- localStorage 变量在哪里与 Redux 状态同步以避免我的 Reducer 中的副作用?
【问题讨论】:
标签: reactjs cookies react-router jwt session-cookies