保持 React 基于 Cookie 的身份验证状态
Posted
技术标签:
【中文标题】保持 React 基于 Cookie 的身份验证状态【英文标题】:Persist React Cookie-based Authentication state 【发布时间】: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 中的副作用?【问题讨论】:
【参考方案1】:我绝对不是这方面的专家,但在我的应用程序中,每当我设置或删除 httpOnly JWT cookie 时,我也会设置/删除一个常规 cookie,其中包含有关用户是否登录以及他们的角色的信息.然后,您可以在客户端检查一些内容,而不会暴露任何敏感内容。
【讨论】:
以上是关于保持 React 基于 Cookie 的身份验证状态的主要内容,如果未能解决你的问题,请参考以下文章
React Native - 在 WebView 中使用 cookie 进行身份验证
如何在 React/NodeJS 身份验证流程中使用 httpOnly cookie 获取用户数据