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)
在我看来,这是最好的解决方案。
/login如果是一个简单的登录页面而无需进一步重定向,@Burhan 的解决方案效果很好。在我的场景中,登录页面仅检查凭据,localStorage如果凭据不可用或过期,则进一步重定向到 IdP 登录页面。
以下代码片段演示了我使用react-router-dom@6联合登录/SSOaws-amplify的解决方案。请注意,它们并不完整或可运行,只是解释其工作原理。
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)
aws-amplify启动联合登录过程之前,将原始 URL 存储到sessionStorage: const login = async () => {
sessionStorage.setItem('beforeLogin', location.state?.from?.pathname);
await Auth.federatedSignIn();
};
Run Code Online (Sandbox Code Playgroud)
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。