如何设置只有当某人登录时才能访问的专用路由



我正在尝试创建一个具有react google登录SSO身份验证的网站,我想创建一个私有路由,如果没有用户登录,则没有人可以访问这些路由,甚至可以看到侧边栏组件。并且将始终重定向到登录页面,即使他们试图通过url访问路由。

这是我的app.js

function App() {
const [value,setValue] = useState()
const [loggedIn, setLoggedIn] = useState()

return (
<>
<Column style={{ width: "100%" }}>
<Row horizontal="start" style={{ backgroundColor: "#0C5494" }}>
<a href="/">
<img alt="logo" className="photo" src={logo}/>
</a> 
</Row>
<BrowserRouter>
<Row >
<Column
flexGrow={1}
>
<PrivateRoute>
<Route path="/" element={<Sidebar/>}></Route>
</PrivateRoute>
</Column>
<Column
vertical="start"
flexGrow={100}
// style={{ backgroundColor: "pink"}}
>
<div className="mainContent">
<AuthContext.Provider value={{loggedIn,setLoggedIn}}>
<TableCountContext.Provider value={{value,setValue}}>
<PrivateRoute>
<Route exact path="/" element={<RealHome/>}></Route>
<Route exact path="/search" element={<Home/>}></Route>

<Route path="/login" element={<Login/>}></Route>

<Route path="/FAQ" element={<Faq/>}></Route>

<Route path="/Search-sec" element={<SearchSec/>}></Route>
</PrivateRoute>
</TableCountContext.Provider>
</AuthContext.Provider>
</div>

</Column>
</Row>

</BrowserRouter>
</Column>
</>
)
}
export default App

这是我的谷歌登录按钮:

export default function GoogleLoginButton() {
const clientId = "myGoogleID.apps.googleusercontent.com"
const [showLoginButton, setShowLoginButton] = useState(true)
const [showLogoutButton, setShowLogoutButton] = useState(false)
const {loggedIn,setLoggedIn} = useContext(AuthContext)
let navigate = useNavigate()
const onLoginSuccess = (res) =>{
console.log("Login Success:", res.profileObj);
setShowLoginButton(false)
setShowLogoutButton(true)
setLoggedIn(localStorage.getItem('isLoggedIn'))
localStorage.setItem('isLoggedIn', true);
console.log(localStorage.getItem('isLoggedIn'))
console.log(loggedIn)
navigate(`/`)
}
const onLoginFailure = (res)=>{
console.log("Login Failed:", res)
}
const onSignoutSuccess = () =>{
alert("You have been signed out successfully.")
setShowLoginButton(true)
setShowLogoutButton(false)
setLoggedIn(localStorage.getItem('isLoggedIn'))
localStorage.setItem('isLoggedIn', false);
console.log(localStorage.getItem('isLoggedIn'))
console.log(loggedIn)
}


return (
<div>
{showLoginButton ?
<GoogleLogin
clientId={clientId}
buttonText="Login"
onSuccess={onLoginSuccess}
onFailure={onLoginFailure}
cookiePolicy={"single_host_origin"}
isSignedIn={true}
/> : null }
{showLogoutButton ?
<GoogleLogout
clientId={clientId}
buttonText="Sign Out"
onLogoutSuccess={onSignoutSuccess}
/> : null}

</div>
)
}

这是我的PrivateRoute.js

import React, {useContext} from "react"
import {Navigate,Route,Routes} from "react-router-dom"
import { AuthContext } from "./Contexts"
export default function PrivateRoute({ component: Component, ...rest }) {
const { loggedIn } = useContext(AuthContext)
return (
<Routes>
<Route
{...rest}
render={props => {
return loggedIn ? <Component {...props} /> : <Navigate to="/login" />
}}
></Route>
</Routes>
)
}

这是我的Contexts.js

import { createContext } from "react";
export const TableCountContext = createContext(null)
export const AuthContext = createContext(false)

以下答案适用于react-router版本6。

根据您是否登录有条件地添加路由,并根据您想要的内容添加一个或多个重定向:

<Routes>
<Route path={"/"} element={ <StartPage/> }/>
<Route path={"/example"} element={ <ExamplePage/> }/>
<Route path={"/otherpage"} element={ <AnotherPage/> }/>
{
isLoggedIn ?
[ 
// add as many as you'd like here
<Route path={"/loggedinpage"} element={ <LoggedInPage/> }/>
]
:
null
}
// take care of redirects for all paths that doesn't match the defined
<Route path={"*"} element={ <Navigate replace to={ "/" }/> }/>
</Routes>

当没有为登录用户定义路径时,catch-all将匹配这些路径,并将用户重定向到/,而当存在这些路径时(例如,用户已登录(,将匹配有问题的路径,并显示相应的内容。

提醒一句:注意,如果你计划从后端提供自定义内容,你需要有一些安全的机制来知道用户是否真的登录了,例如,不要只相信前端会说";我以这个和这个用户的身份登录;。你可能已经知道了,但只是说清楚而已。

我使用redux进行登录,在这种情况下,您可以编写react路由器组件,以检查用户是否已登录

const ProtectedRoute = ({ component: Component, ...props }) => {
const { isLoggedIn } = props;
return (
<Route render={(props) => (
!isLoggedIn ? <Component {...props} /> : <Redirect to={{/loginPage}}>/>
)} {...props} />
);
};
const mapStateToProps = (state) => ({
isLoggedIn: state.user.isLoggedIn
})
export default connect(mapStateToProps)(ProtectedRoute)

最新更新