как настроить частные маршруты, доступ к которым возможен только при входе в систему?

#javascript #reactjs #react-hooks #react-router #google-login

Вопрос:

Я пытаюсь создать веб-сайт с аутентификацией единого входа в систему react-google, и я хотел бы создать частный маршрут, где, если пользователь не вошел в систему, никто не сможет получить доступ к этим маршрутам и даже увидеть компонент боковой панели. И всегда будут перенаправлены на страницу входа в систему, даже если они попытаются получить доступ к маршруту по URL-адресу.

Вот мой app.js

 function App() {  const [value,setValue] = useState()  const [loggedIn, setLoggedIn] = useState()     return (  lt;gt;  lt;Column style={{ width: "100%" }}gt;  lt;Row horizontal="start" style={{ backgroundColor: "#0C5494" }}gt;  lt;a href="/"gt;  lt;img alt="logo" className="photo" src={logo}/gt;  lt;/agt;   lt;/Rowgt;  lt;BrowserRoutergt;  lt;Row gt;  lt;Column  flexGrow={1}  gt;  lt;PrivateRoutegt;  lt;Route path="/" element={lt;Sidebar/gt;}gt;lt;/Routegt;  lt;/PrivateRoutegt;  lt;/Columngt;  lt;Column  vertical="start"  flexGrow={100}  // style={{ backgroundColor: "pink"}}  gt;  lt;div className="mainContent"gt;  lt;AuthContext.Provider value={{loggedIn,setLoggedIn}}gt;  lt;TableCountContext.Provider value={{value,setValue}}gt;  lt;PrivateRoutegt;  lt;Route exact path="/" element={lt;RealHome/gt;}gt;lt;/Routegt;  lt;Route exact path="/search" element={lt;Home/gt;}gt;lt;/Routegt;    lt;Route path="/login" element={lt;Login/gt;}gt;lt;/Routegt;    lt;Route path="/FAQ" element={lt;Faq/gt;}gt;lt;/Routegt;    lt;Route path="/Search-sec" element={lt;SearchSec/gt;}gt;lt;/Routegt;  lt;/PrivateRoutegt;  lt;/TableCountContext.Providergt;  lt;/AuthContext.Providergt;  lt;/divgt;    lt;/Columngt;  lt;/Rowgt;    lt;/BrowserRoutergt;  lt;/Columngt;  lt;/gt;  ) }  export default App  

вот моя кнопка входа в Google:

 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) =gt;{  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)=gt;{  console.log("Login Failed:", res)  }   const onSignoutSuccess = () =gt;{  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 (  lt;divgt;  {showLoginButton ?  lt;GoogleLogin  clientId={clientId}  buttonText="Login"  onSuccess={onLoginSuccess}  onFailure={onLoginFailure}  cookiePolicy={"single_host_origin"}  isSignedIn={true}  /gt; : null }  {showLogoutButton ?  lt;GoogleLogout  clientId={clientId}  buttonText="Sign Out"  onLogoutSuccess={onSignoutSuccess}  /gt; : null}    lt;/divgt;  ) }  

Вот мой 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 (  lt;Routesgt;  lt;Route  {...rest}  render={props =gt; {  return loggedIn ? lt;Component {...props} /gt; : lt;Navigate to="/login" /gt;  }}  gt;lt;/Routegt;  lt;/Routesgt;  ) }  

Вот мой Contexts.js

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

Комментарии:

1. Добавьте некоторые маршруты условно в зависимости от того, вошел ли пользователь в систему. Затем по умолчанию / все, что перенаправляет по желанию для других URL-адресов. Последнее может быть выполнено с Redirect помощью in react-router lt; v6 и с Navigate помощью for gt;= v6.

2. @быстрые рефлексы я обновил коды, отображаемые в моем вопросе, исходя из моего понимания вашего комментария, но я все еще могу получить доступ к своим личным маршрутам, когда я ввожу их в URL.

3. Вместо этого добавил ответ

Ответ №1:

Следующий ответ относится к react-router версии 6.

Добавляйте маршруты условно в зависимости от того, вошли вы в систему или нет, и добавляйте одно или несколько перенаправлений в зависимости от того, что вы хотите:

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

Если для вошедших в систему пользователей не определены пути, эти пути будут сопоставлены системой «Все включено», и пользователь будет перенаправлен, в / то время как при наличии этих путей (например, пользователь вошел в систему) соответствующий путь будет сопоставлен и будет показано соответствующее содержимое.

Слово предостережения: обратите внимание, что если вы планируете предоставлять пользовательский контент со своего бэкенда, вам необходимо иметь какой-то безопасный механизм, чтобы знать, действительно ли пользователь вошел в систему или нет, например, не просто доверять интерфейсу, говорящему «Я вошел в систему как этот и этот пользователь». Вы, вероятно, уже знаете это, но просто разъясняете это.

Ответ №2:

я использовал redux для входа в систему, в этом случае вы можете написать react-router-компонент, чтобы проверить, вошел ли пользователь в систему или нет

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

Комментарии:

1. Не могли бы вы, пожалуйста, объяснить это подробнее? Спасибо

2. вы можете использовать метод визуализации внутри маршрута , я написал условие для динамической проверки , если пользователь вошел в систему , маршрут к компонентам, если нет, маршрут на страницу входа в систему… затем внутри вашего lt;Коммутатораgt; вы можете импортировать этот защищенный маршрут

3. Привет, спасибо за ваше объяснение, но я использую маршрутизатор react v6, поэтому lt;Переключательgt; не работает. Но я обновил коды, отображаемые в моем вопросе, который очень похож на ваш, но я все еще могу получить доступ к своим личным маршрутам, когда пользователь не вошел в систему.