我已经为特定的页面打了PrivateRoute分.除PrivateRoute页外,所有页都是公共的(Anyone can view them).如果用户是未经授权的,则路由始终导航到在logUser函数中声明的页面.
我正在使用Python Django来构建API.
App.js
import "./App.css";
import { Fragment } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import Login from "./pages/Login";
import Register from "./pages/Register";
import Post from "./pages/Post";
import Details from "./pages/Details";
import HeaderNav from "./components/Navbar";
import Footerbar from "./components/Footer";
import PrivateRoute from "./utils/PrivateRoute";
import { AuthProvider } from "./context/AuthContext";
function App() {
return (
<Fragment>
<BrowserRouter>
<AuthProvider>
<HeaderNav />
<div className="bg-gray-100 w-full h-full">
<Routes>
<Route element={<PrivateRoute />} path="/post">
<Route element={<Post />} path="/post" />
</Route>
<Route element={<Home />} path="/" />
<Route element={<Post />} path="/post" />
<Route element={<Details />} path="/post/:id" />
<Route element={<Register />} path="/register" />
<Route element={<Login />} path="/login" />
</Routes>
</div>
<Footerbar />
</AuthProvider>
</BrowserRouter>
</Fragment>
);
}
export default App;
PrivateRoute.js
import { Navigate, Outlet } from "react-router-dom";
import { useContext } from "react";
import AuthContext from "../context/AuthContext";
const PrivateRoute = () => {
const { username } = useContext(AuthContext);
return username ? <Outlet /> : <Navigate to="/login" />;
};
export default PrivateRoute;
AuthContext.js
import { createContext, useEffect, useState } from "react";
import jwt_decode from "jwt-decode";
import { useNavigate } from "react-router-dom";
const AuthContext = createContext();
export default AuthContext;
export const AuthProvider = ({ children }) => {
let [authTokens, setAuthTokens] = useState(() =>
localStorage.getItem("authTokens")
? JSON.parse(localStorage.getItem("authTokens"))
: null
);
let [username, setUsername] = useState(() =>
localStorage.getItem("authTokens")
? jwt_decode(localStorage.getItem("authTokens"))
: null
);
let [loading, setLoading] = useState(true);
const navigate = useNavigate();
let loginUser = async (e) => {
e.preventDefault();
const response = await fetch("http://127.0.0.1:8000/api/token/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username: e.target.username.value,
password: e.target.password.value,
}),
});
let data = await response.json();
if (response.status === 200) {
setAuthTokens(data);
setUsername(jwt_decode(data.access));
localStorage.setItem("authTokens", JSON.stringify(data));
navigate("/");
} else {
alert("Incorrect username or password!");
}
};
const logoutUser = () => {
setAuthTokens(null);
setUsername(null);
localStorage.removeItem("authTokens");
navigate("/"); // Always navigating this page when the user is unauthorized
};
const updateToken = async () => {
const response = await fetch(
"http://127.0.0.1:8000/api/token/refresh/",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ refresh: authTokens?.refresh }),
}
);
let data = await response.json();
if (response.status === 200) {
setAuthTokens(data);
setUsername(jwt_decode(data.access));
localStorage.setItem("authTokens", JSON.stringify(data));
} else {
logoutUser();
}
if (loading) {
setLoading(false);
}
};
const contextData = {
username: username,
authTokens: authTokens,
loginUser: loginUser,
logoutUser: logoutUser,
};
useEffect(() => {
if (loading) updateToken();
const fourMinutes = 4 * 60 * 1000;
const interval = setInterval(() => {
if (authTokens) {
updateToken();
}
}, fourMinutes);
return () => clearInterval(interval);
}, [authTokens, loading]);
return (
<AuthContext.Provider value={contextData}>
{loading ? null : children}
</AuthContext.Provider>
);
};
如果你看到logoutUser
功能,在那里导航的页面,总是重定向到这个页面,如果用户是未经授权的.
我想限制只发布页面,这就是为什么我使用PrivateRoute
.其他页面将向所有人开放.
我被困了一段时间,想不出问题所在.