React - 未通过身份验证时重定向到登录页面
Posted
技术标签:
【中文标题】React - 未通过身份验证时重定向到登录页面【英文标题】:React - redirect to login page when not authenticated 【发布时间】:2022-01-17 08:24:03 【问题描述】:这是我的主要反应文件:
// App.tsx
const App: FC = () =>
const isLoggedIn: boolean = localStorage.getItem('logged_user') !== null;
return (
<BrowserRouter>
<Routes>
<Route path="/main" element=isLoggedIn ? <Main/> : <Navigate to='/login'/>/>
<Route path="/about" element=isLoggedIn ? <About/> : <Navigate to='/login'/>/>
<Route path="/login" element=<Login/>/>
</Routes>
</BrowserRouter>
);
export default App;
登录后,我将用户存储在本地存储中。
我想实现在用户未通过身份验证时重定向到 /login 页面的行为(当它未存储在本地存储中时)。
通常,上述方法有效,但仅在某些时候有效。有时,当我转到 '/main' 时,即使我已经登录,我也会被重定向到 '/login'。我认为这是由 React 的性质引起的重新渲染。
我该如何处理?
【问题讨论】:
我猜重定向到“/login”第一次工作,你登录,然后尝试导航到“/main”或“/about”并被重定向回“/ login”,直到您执行诸如重新加载页面之类的操作并读取任何持久的“logged_user”状态,然后卡住不退出并重定向回“/login”? 不确定注销部分,但其余部分是准确的。 【参考方案1】:我猜第一次重定向到“/login”是有效的,你登录,然后尝试导航到“/main”或“/about”并被重定向回“/login”,直到你这样做类似于页面重新加载并读取任何持久的“logged_user”状态,然后卡住不退出并被重定向回“/login”。
您应该将 isLoggedIn
值存储在本地状态中,从 localStorage 初始化,并在应用程序中提供一种切换状态的方法。使用 useEffect
挂钩将本地状态更改持久化回 localStorage。
例子:
const App: FC = () =>
const [isLoggedIn, setIsLoggedIn] = useState<boolean>(
() => localStorage.getItem('logged_user') !== null
);
useEffect(() =>
localStorage.setItem('logged_user', JSON.stringify(isLoggedIn));
, [isLoggedIn]);
const logIn = () => setIsLoggedIn(true);
// pass this callback to components you want to allow logging out
// it will update the local state and then get persisted
const logOut = () => setIsLoggedIn(false);
return (
<BrowserRouter>
<Routes>
<Route path="/main" element=isLoggedIn ? <Main/> : <Navigate to='/login'/>/>
<Route path="/about" element=isLoggedIn ? <About/> : <Navigate to='/login'/>/>
<Route path="/login" element=<Login onLogIn=logIn />/>
</Routes>
</BrowserRouter>
);
【讨论】:
【参考方案2】:我喜欢这样做的方式是创建一个<PrivateLink />
组件,以便清楚地知道嵌套的任何路由都需要经过身份验证的用户。
const PrivateRoute = (props: children: React.ReactNode ): JSX.Element =>
const children = props
const isLoggedIn: boolean = localStorage.getItem('logged_user') !== null;
const location = useLocation()
return isLoggedIn ? (
<>children</>
) : (
<Navigate
replace=true
to="/login"
state= from: `$location.pathname$location.search`
/>
)
然后在你的 App.tsx 中
const App: FC = () => (
<BrowserRouter>
<Routes>
<Route path="/main" element=<PrivateRoute> <Main/> </PrivateRoute>/>
<Route path="/about" element=<PrivateRoute> <About/> </PrivateRoute>/>
<Route path="/login" element=<Login/>/>
</Routes>
</BrowserRouter>
)
作为额外的附加功能,from
变量传递给<PrivateRoute />
组件中的状态,允许您将用户重定向回登录后他们来自的任何页面。
【讨论】:
以上是关于React - 未通过身份验证时重定向到登录页面的主要内容,如果未能解决你的问题,请参考以下文章
使用 react-router-v5 和 redux-toolkit 登录时重定向页面
Flask - 如果当前用户未通过身份验证,如何重定向到登录页面?