登录React Router后如何重定向到上一页?

naj*_*lhc 10 reactjs react-router

我希望重定向到用户完成登录后最后访问的页面,我为此使用了react-router。我怎样才能做到这一点?

Bur*_*han 10

您可以使用查询字符串来完成此操作。

添加依赖查询字符串添加到您的反应应用程序中。

每当用户尝试访问受保护的路径时,如果用户尚未登录,则必须重定向到登录屏幕。为此,您将执行类似的操作。

history.push('/login');
Run Code Online (Sandbox Code Playgroud)

但我们可以将前一个作为查询传递,如下所示。useLocation我们可以使用from 来获取之前的路径react-router

const prevLocation = useLocation();
history.push(`/login?redirectTo=${prevLocation}`);
Run Code Online (Sandbox Code Playgroud)

现在登录成功后,我们可以获取之前路径中传递的查询字符串。如果之前的路径是 ,我们可以设置一个默认路径null

const handleSuccessLogin = () => {
      const location = useLocation();
      const { redirectTo } = queryString.parse(location.search);
      history.push(redirectTo == null ? "/apps" : redirectTo);
 };
Run Code Online (Sandbox Code Playgroud)

在我看来,这是最好的解决方案。


Eri*_*ang 5

/login如果是一个简单的登录页面而无需进一步重定向,@Burhan 的解决方案效果很好。在我的场景中,登录页面仅检查凭据,localStorage如果凭据不可用或过期,则进一步重定向到 IdP 登录页面。

以下代码片段演示了我使用react-router-dom@6联合登录/SSOaws-amplify的解决方案。请注意,它们并不完整或可运行,只是解释其工作原理。

  1. 在应用程序组件中使用PrivateRoute(有关详细信息,请参阅react-router-dom@6文档)检查登录凭据是否可用(auth通过单独的AuthContext提供,该AuthContext不属于本主题):
const PrivateRoute: React.FC<{user: AuthenticatedUser}> = ({ user }) => {
  const location = useLocation();
  return user ? <Outlet /> : <Navigate to="/login" replace state={{ from: location }} />;
};
Run Code Online (Sandbox Code Playgroud)

在 App 组件中应用PrivateRoute/

return (
      <Routes>
        <Route path="/" element={<PrivateRoute user={auth.user} />}>
          ... // Other routes
        </Route>
        <Route path="/login" element={<Login />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
);
Run Code Online (Sandbox Code Playgroud)
  1. 在登录组件中,在调用aws-amplify启动联合登录过程之前,将原始 URL 存储到sessionStorage
  const login = async () => {
    sessionStorage.setItem('beforeLogin', location.state?.from?.pathname);
    await Auth.federatedSignIn();
  };
Run Code Online (Sandbox Code Playgroud)
  1. 在联合登录回调处理程序中,获取位置状态和 url,sessionStorage并使用调用 auth context 后可用的任何一个来设置经过身份验证的用户:
    Auth.currentAuthenticatedUser()
      .then((currentUser) => {
        if (currentUser) {
          auth.setUser(currentUser);
          const beforeLoginUrl = sessionStorage.getItem('beforeLogin');
          sessionStorage.removeItem('beforeLogin');
          navigate(beforeLoginUrl ?? location.state?.from ?? '/default');
        }
      })
      .catch(console.error);
Run Code Online (Sandbox Code Playgroud)

我需要检查两者,就像我的情况一样,如果登录组件找到有效的凭据,它根本不会重定向到 IdP,因此sessionStorage不会有 URL,但只有 URL location.state?.from