在 ReactJS 钩子中刷新页面时丢失身份验证状态



当我使用有效凭据登录服务器将 JWT 发送到浏览器时,我将此 JWT 存储在本地存储页面中,重定向到主页一切正常,在主页中我有 loadUser 函数,该功能向服务器发送请求以获取有效用户的用户详细信息,但当我刷新页面时,主页永远不会执行,因为身份验证状态返回为 false 并且页面从主页重定向到登录页面 这是应用程序.js

import React, { Fragment } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Navbar from "./components/layout/Navbar";
import Home from "./components/pages/Home";
import Login from "./components/auth/Login";
import PrivateRoute from "./components/routing/PrivateRoute";
import "./App.css";
const App = () => {
return (
<AuthState>
<Router>
<Fragment>
<Navbar />
<div className="container">
<Alerts />
<Switch>
<PrivateRoute exact path="/" component={Home} />
<Route exact path="/login" component={Login} />
</Switch>
</div>
</Fragment>
</Router>
</AuthState>
);
};
export default App;
这是我的授权代码,成功登录后我的状态会发生变化

import React, { useReducer } from "react";
import axios from "axios";
import AuthContext from "./authContext";
import authReducer from "./authReducer";
import {
USER_LOADED,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
} from "../types";
const AuthState = props => {
const initialState = {
isAuthenticated: null,
user: null,
};
const [state, dispatch] = useReducer(authReducer, initialState);
// Load User
const loadUser = async () => {
if (localStorage.token) {
setAuthToken(localStorage.token);
}
try {
const res = await axios.get("/api/auth");
dispatch({ type: USER_LOADED, payload: res.data });
} catch (err) {
dispatch({ type: AUTH_ERROR });
}
};
// Login User
const login = async formData => {
const config = {
headers: {
"Content-Type": "application/json"
}
};
try {
const res = await axios.post("api/auth", formData, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
});
loadUser();
} catch (err) {
dispatch({
type: LOGIN_FAIL,
payload: err.response.data.msg
});
}
};
return (
<AuthContext.Provider
value={{
isAuthenticated: state.isAuthenticated,
user: state.user,
loadUser,
login,
}}
>
{props.children}
</AuthContext.Provider>
);
};
export default AuthState;

这是化简码身份验证化简器.js

import {
USER_LOADED,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
} from "../types";
export default (state, action) => {
switch (action.type) {
case USER_LOADED:
return {
...state,
isAuthenticated: true,
user: action.payload
};
case LOGIN_SUCCESS:
localStorage.setItem("token", action.payload.token);
return {
...state,
isAuthenticated: true
};
case AUTH_ERROR:
case LOGIN_FAIL:
localStorage.removeItem("token");
return {
...state,
isAuthenticated: false,
user: null,
};
default:
return state;
}
};
This is private route
import React, { useContext } from "react";
import { Route, Redirect } from "react-router-dom";
import AuthContext from "../../context/auth/authContext";
const PrivateRoute = ({ component: Component, ...rest }) => {
const authContext = useContext(AuthContext);
const { isAuthenticated, loading } = authContext;
return (
<Route
{...rest}
render={props =>
!isAuthenticated && !loading ? (
<Redirect to="/login" />
) : (
<Component {...props} />
)
}
/>
);
};
export default PrivateRoute;

这是意料之中的。

如果要保留令牌,则应将其保存在localStoragecookie中。

然后,如果您使用的是hooks,则应检查令牌在componentDidMountuseEffect(具有 void 依赖项数组(中是否存在和有效性。

如果您能向我们展示您在哪里发出AJAX请求,那就太好了,因为例如,如果您正在使用Axios则可以将此逻辑封装在request拦截器中。

可能是用于用户身份验证/授权的 JSON Web 令牌。您能给我们更多关于这方面的信息吗?

相关内容

  • 没有找到相关文章

最新更新