身份验证响应后如何呈现反应路线?
How to render react routes after auth response?
当有人访问我的网页时,我首先检查用户是否经过身份验证。在呈现路由之前,我需要等待 GET /auth/loggedin
请求的响应,以便我知道是否应该重定向到 /login
或 /
。我已将条件呈现添加到 App.js
组件,但它总是将用户重定向到 /login
,即使用户已通过身份验证。
App.js:
import { useEffect, useState } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import AuthContext from "./contexts/authContext";
import { apiLoggedIn } from "./api/auth";
import ProtectedRoute from "./components/ProtectedRoute";
import Document from "./pages/Document";
import { Login } from "./pages/Login";
import { Signup } from "./pages/Signup";
import Layout from "./components/Layout";
import PublicRoute from "./components/PublicRoute";
export const App = () => {
const [auth, setAuth] = useState({ isAuth: undefined, user: undefined });
useEffect(() => {
apiLoggedIn()
.then((res) => {
setAuth({ isAuth: true, user: res.data.userData });
})
.catch((err) => {
if (err.response) {
setAuth({ isAuth: false, user: {} });
} else if (err.request) {
setAuth({ isAuth: false, user: {} });
console.log(err.request);
} else {
setAuth({ isAuth: false, user: {} });
console.log(err.message);
}
});
}, []);
return (
<>
{auth.isAuth !== undefined ? (
<AuthContext.Provider value={{ auth, setAuth }}>
<BrowserRouter>
<Routes>
<Route
path="/"
element={
<ProtectedRoute redirectTo="/login">
<Layout />
</ProtectedRoute>
}
>
<Route index element={<Document />} />
</Route>
<Route
path="/signup"
element={
<PublicRoute>
<Signup />
</PublicRoute>
}
/>
<Route
path="/login"
element={
<PublicRoute>
<Login />
</PublicRoute>
}
/>
</Routes>
</BrowserRouter>
</AuthContext.Provider>
) : (
""
)}
</>
);
};
./api/auth.js
import axios from "axios";
export const apiLoggedIn = () => {
return axios.get("/auth/loggedin");
};
./components/ProtectedRoute.js
import { useContext } from "react";
import AuthContext from "../contexts/authContext";
import { Navigate } from "react-router-dom";
const ProtectedRoute = ({ children, redirectTo }) => {
const { isAuth } = useContext(AuthContext);
return isAuth ? children : <Navigate to={redirectTo} />;
};
export default ProtectedRoute;
./components/PublicRoute.js
import { useContext } from "react";
import AuthContext from "../contexts/authContext";
import { Navigate } from "react-router-dom";
const PublicRoute = ({ children }) => {
const { isAuth } = useContext(AuthContext);
return isAuth ? <Navigate to={"/"} /> : children;
};
export default PublicRoute;
./contexts/authContext.js
import { createContext } from "react";
const AuthContext = createContext({
auth: { isAuth: false, user: {} },
setAuth: () => {},
});
export default AuthContext;
AuthContext
值是一个具有 auth
和 setAuth
属性的对象
<AuthContext.Provider value={{ auth, setAuth }}>
...
</AuthContext.Provider>
但在路由包装器中,您引用了一个 isAuth
属性,它将 始终 未定义,即错误。
const ProtectedRoute = ({ children, redirectTo }) => {
const { isAuth } = useContext(AuthContext);
return isAuth ? children : <Navigate to={redirectTo} />;
};
这就是重定向总是发生的原因。要解决此问题,请确保在整个代码中引用相同的上下文值。
要么指定一个 isAuth
上下文值:
<AuthContext.Provider value={{ isAuth: auth.isAuth, setAuth }}>
...
</AuthContext.Provider>
或修复包装器:
const ProtectedRoute = ({ children, redirectTo }) => {
const { auth } = useContext(AuthContext);
return auth.isAuth ? children : <Navigate to={redirectTo} />;
};
...
const PublicRoute = ({ children }) => {
const { auth } = useContext(AuthContext);
return auth.isAuth ? <Navigate to={"/"} /> : children;
};
密钥名称未在身份验证提供程序中正确传递,应该按以下方式传递,这里是示例沙箱演示:https://codesandbox.io/s/routes-4c5oh?file=/src/App.js
<AuthContext.Provider value={{ isAuth:auth, setAuth }}>
或在每个地方将密钥更改为auth
。在 Public 和受保护的路线中,例如以下
const { auth:{isAuth} } = useContext(AuthContext);
您的上下文具有以下形状:
{
"auth": {
"isAuth": true,
"user": {...},
},
"setAuth": function ...
}
您必须将 ProtectedRoute 更新为
const ProtectedRoute = ({ children, redirectTo }) => {
const { auth } = useContext(AuthContext);
return auth.isAuth ? children : <Navigate to={redirectTo} />;
};
您必须将 PublicRoute 更新为
const PublicRoute = ({ children }) => {
const { auth } = useContext(AuthContext);
return auth.isAuth ? <Navigate to={"/"} /> : children;
};
当有人访问我的网页时,我首先检查用户是否经过身份验证。在呈现路由之前,我需要等待 GET /auth/loggedin
请求的响应,以便我知道是否应该重定向到 /login
或 /
。我已将条件呈现添加到 App.js
组件,但它总是将用户重定向到 /login
,即使用户已通过身份验证。
App.js:
import { useEffect, useState } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import AuthContext from "./contexts/authContext";
import { apiLoggedIn } from "./api/auth";
import ProtectedRoute from "./components/ProtectedRoute";
import Document from "./pages/Document";
import { Login } from "./pages/Login";
import { Signup } from "./pages/Signup";
import Layout from "./components/Layout";
import PublicRoute from "./components/PublicRoute";
export const App = () => {
const [auth, setAuth] = useState({ isAuth: undefined, user: undefined });
useEffect(() => {
apiLoggedIn()
.then((res) => {
setAuth({ isAuth: true, user: res.data.userData });
})
.catch((err) => {
if (err.response) {
setAuth({ isAuth: false, user: {} });
} else if (err.request) {
setAuth({ isAuth: false, user: {} });
console.log(err.request);
} else {
setAuth({ isAuth: false, user: {} });
console.log(err.message);
}
});
}, []);
return (
<>
{auth.isAuth !== undefined ? (
<AuthContext.Provider value={{ auth, setAuth }}>
<BrowserRouter>
<Routes>
<Route
path="/"
element={
<ProtectedRoute redirectTo="/login">
<Layout />
</ProtectedRoute>
}
>
<Route index element={<Document />} />
</Route>
<Route
path="/signup"
element={
<PublicRoute>
<Signup />
</PublicRoute>
}
/>
<Route
path="/login"
element={
<PublicRoute>
<Login />
</PublicRoute>
}
/>
</Routes>
</BrowserRouter>
</AuthContext.Provider>
) : (
""
)}
</>
);
};
./api/auth.js
import axios from "axios";
export const apiLoggedIn = () => {
return axios.get("/auth/loggedin");
};
./components/ProtectedRoute.js
import { useContext } from "react";
import AuthContext from "../contexts/authContext";
import { Navigate } from "react-router-dom";
const ProtectedRoute = ({ children, redirectTo }) => {
const { isAuth } = useContext(AuthContext);
return isAuth ? children : <Navigate to={redirectTo} />;
};
export default ProtectedRoute;
./components/PublicRoute.js
import { useContext } from "react";
import AuthContext from "../contexts/authContext";
import { Navigate } from "react-router-dom";
const PublicRoute = ({ children }) => {
const { isAuth } = useContext(AuthContext);
return isAuth ? <Navigate to={"/"} /> : children;
};
export default PublicRoute;
./contexts/authContext.js
import { createContext } from "react";
const AuthContext = createContext({
auth: { isAuth: false, user: {} },
setAuth: () => {},
});
export default AuthContext;
AuthContext
值是一个具有 auth
和 setAuth
属性的对象
<AuthContext.Provider value={{ auth, setAuth }}>
...
</AuthContext.Provider>
但在路由包装器中,您引用了一个 isAuth
属性,它将 始终 未定义,即错误。
const ProtectedRoute = ({ children, redirectTo }) => {
const { isAuth } = useContext(AuthContext);
return isAuth ? children : <Navigate to={redirectTo} />;
};
这就是重定向总是发生的原因。要解决此问题,请确保在整个代码中引用相同的上下文值。
要么指定一个 isAuth
上下文值:
<AuthContext.Provider value={{ isAuth: auth.isAuth, setAuth }}>
...
</AuthContext.Provider>
或修复包装器:
const ProtectedRoute = ({ children, redirectTo }) => {
const { auth } = useContext(AuthContext);
return auth.isAuth ? children : <Navigate to={redirectTo} />;
};
...
const PublicRoute = ({ children }) => {
const { auth } = useContext(AuthContext);
return auth.isAuth ? <Navigate to={"/"} /> : children;
};
密钥名称未在身份验证提供程序中正确传递,应该按以下方式传递,这里是示例沙箱演示:https://codesandbox.io/s/routes-4c5oh?file=/src/App.js
<AuthContext.Provider value={{ isAuth:auth, setAuth }}>
或在每个地方将密钥更改为auth
。在 Public 和受保护的路线中,例如以下
const { auth:{isAuth} } = useContext(AuthContext);
您的上下文具有以下形状:
{
"auth": {
"isAuth": true,
"user": {...},
},
"setAuth": function ...
}
您必须将 ProtectedRoute 更新为
const ProtectedRoute = ({ children, redirectTo }) => {
const { auth } = useContext(AuthContext);
return auth.isAuth ? children : <Navigate to={redirectTo} />;
};
您必须将 PublicRoute 更新为
const PublicRoute = ({ children }) => {
const { auth } = useContext(AuthContext);
return auth.isAuth ? <Navigate to={"/"} /> : children;
};