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】:

我喜欢这样做的方式是创建一个&lt;PrivateLink /&gt; 组件,以便清楚地知道嵌套的任何路由都需要经过身份验证的用户。

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 变量传递给&lt;PrivateRoute /&gt; 组件中的状态,允许您将用户重定向回登录后他们来自的任何页面。

【讨论】:

以上是关于React - 未通过身份验证时重定向到登录页面的主要内容,如果未能解决你的问题,请参考以下文章

使用 react-router-v5 和 redux-toolkit 登录时重定向页面

成功登录后登录页面未重定向到主页

Flask - 如果当前用户未通过身份验证,如何重定向到登录页面?

在 ASP.NET Core 中未经授权时重定向到登录

带有访客和身份验证中间件的 Nuxt 身份验证将经过身份验证的用户在刷新时重定向到错误的页面

仅当未使用 @azure/msal-react 进行身份验证时才重定向 onLoad