#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
помощью inreact-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; не работает. Но я обновил коды, отображаемые в моем вопросе, который очень похож на ваш, но я все еще могу получить доступ к своим личным маршрутам, когда пользователь не вошел в систему.