我正在使用accessToken和refreshToken来登录过程。我决定使用httpOnly将accessToken存储在React useState中,将refreshToken存储在Cookie中。 accessToken保存在state中。 freshToken是保存的Cookie。当我登录页面时,我可以访问下一页,但是当我按 F5 时,我会返回登录页面。获取 accessToken 效果很好,但我不知道为什么该网站强迫我去登录网站。这是我的代码
const ProtectedRoute = ({ element, allowedRoles }) => {
const { accessToken } = useContext(RoleContext);
let role = "";
if (accessToken !== "") {
const decodedPayLoad = jwtDecode(accessToken);
role = decodedPayLoad.role;
}
if (!accessToken) {
return <Navigate to="/auth/login" replace />;
}
if (!allowedRoles.includes(role)) {
return <Navigate to="/" replace />;
}
return element;
};
export default ProtectedRoute;
// Create an Axios instance
const axiosInstance = axios.create({
baseURL: process.env.REACT_APP_API_BASE_URL || "http://localhost:3000", // Adjust the baseURL according to your backend API
withCredentials: true,
});
// Axios request interceptor
axiosInstance.interceptors.request.use(
(config) => {
const accessToken = RoleContext.accessToken;
if (accessToken) {
config.headers["Authorization"] = `Bearer ${accessToken}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Axios response interceptor
axiosInstance.interceptors.response.use(
(response) => response,
async (error) => {
const {
config,
response: { status },
} = error;
const originalRequest = config;
if (status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
const { setAccessToken } = RoleContext;
const navigate = useNavigate();
try {
const res = await axiosInstance.post("/auth/token");
const newToken = res.data.accessToken;
setAccessToken(newToken);
axios.defaults.headers.common["Authorization"] = `Bearer ${newToken}`;
originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
return axiosInstance(originalRequest);
} catch (err) {
navigate("/auth/login");
return Promise.reject(err);
}
}
return Promise.reject(error);
}
);
export default axiosInstance;
const ProtectedRoute = ({ element, allowedRoles }) => {
const { accessToken } = useContext(RoleContext);
let role = "";
if (accessToken !== "") {
const decodedPayLoad = jwtDecode(accessToken);
role = decodedPayLoad.role;
}
if (!accessToken) {
return <Navigate to="/auth/login" replace />;
}
if (!allowedRoles.includes(role)) {
return <Navigate to="/" replace />;
}
return element;
};
export default ProtectedRoute;
const root = ReactDOM.createRoot(document.getElementById("root"));
const AppRoutes = () => {
const { accessToken } = useContext(RoleContext);
let role = "";
if (accessToken !== "") {
const decodedPayLoad = jwtDecode(accessToken);
role = decodedPayLoad.role;
}
const isAuthenticated = !!accessToken;
console.log(isAuthenticated);
return (
<Routes>
<Route
path="/"
element={
<Navigate
to={
isAuthenticated
? role === "superadmin"
? "/superadmin/index"
: role === "admin"
? "/admin/index"
: "/user/index"
: "/auth/login"
}
replace
/>
}
/>
<Route
path="/superadmin/*"
element={
<ProtectedRoute
element={<SuperAdminLayout />}
allowedRoles={["superadmin"]}
/>
}
/>
<Route
path="/admin/*"
element={
<ProtectedRoute
element={<AdminLayout />}
allowedRoles={["superadmin", "admin"]}
/>
}
/>
<Route
path="/user/*"
element={
<ProtectedRoute
element={<UserLayout />}
allowedRoles={["superadmin", "admin", "user"]}
/>
}
/>
<Route path="/auth/*" element={<AuthLayout />}></Route>
</Routes>
);
};
root.render(
<RoleProvider>
<BrowserRouter>
<AppRoutes />
</BrowserRouter>
</RoleProvider>
);
如果您希望跨页面加载、刷新,甚至在 React 应用程序中的不同选项卡之间保留数据,那么仅依赖组件状态或上下文是不够的。
要有效维护访问令牌等数据,请考虑将其存储在 cookie 或本地存储中。这可以确保即使用户离开或刷新页面,数据仍然可以访问。
您可以创建自定义 React hook,以便在需要时从 cookie 中检索令牌。这种方法允许您在应用程序中轻松访问和使用令牌。