tki*_*m90 5 reactjs react-router react-router-dom
我用来react-router-dom保护整个应用程序。所有路由都受到 ProtectedRoute 组件的保护(请参阅下面的代码),该组件会重定向到外部 url,如果用户未登录,则为单点登录 (SSO) 页面。
当用户转到“/home”时,他们会短暂浏览(“闪现”)受保护的路由,然后重定向到“external-login-page.com/”(登录页面)。如何避免闪烁,使用户只能看到登录页面?
export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({
isAuthenticated,
...rest
}) => {
if (!isAuthenticated) { // redirect if not logged in
return (
<Route
component={() => {
window.location.href = 'http://external-login-page.com/';
return null;
}}
/>
);
} else {
return <Route {...rest} />;
}
};
Run Code Online (Sandbox Code Playgroud)
发布最终对我有用的解决方案:不是阻塞Router,而是阻塞App。
关键是将你App分成两个部分,AuthenticatedApp和UnauthenticatedApp。从那里,根据用户的访问级别延迟加载正确的组件。这样,如果他们未经授权,他们的浏览器甚至根本不会加载AuthenticatedApp。
AuthenticatedApp是整个应用程序、提供程序、路由器等的组件。App.tsx 中的所有内容最初都应该放在这里。UnauthenticatedApp是您希望用户在不允许他们访问应用程序时看到的组件。类似于“未授权。请联系管理员寻求帮助。”应用程序.tsx
const AuthenticatedApp = React.lazy(() => import('./AuthenticatedApp'));
const UnauthenticatedApp = React.lazy(() => import('./UnauthenticatedApp'));
// Dummy function to check if user is authenticated
const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));
const getUser = () => sleep(3000).then(() => ({ user: '' }));
const App: React.FC = () => {
// You should probably use a custom `AuthContext` instead of useState,
// but I kept this for simplicity.
const [user, setUser] = React.useState<{ user: string }>({ user: '' });
React.useEffect(() => {
async function checkIfUserIsLoggedInAndHasPermissions() {
let user;
try {
const response = await getUser();
user = response.user;
console.log(user);
setUser({ user });
} catch (e) {
console.log('Error fetching user.');
user = { user: '' };
throw new Error('Error authenticating user.');
}
}
checkIfUserIsLoggedInAndHasPermissions();
}, []);
return (
<React.Suspense fallback={<FullPageSpinner />}>
{user.user !== '' ? <AuthenticatedApp /> : <UnauthenticatedApp />}
</React.Suspense>
);
};
export default App;
Run Code Online (Sandbox Code Playgroud)
在这里阅读 Kent C Dodd 的精彩文章 [0]!
编辑:找到了另一个使用类似方法的好例子,但有点复杂 - [1]
[0] https://kentcdodds.com/blog/authentication-in-react-applications?ck_subscriber_id=962237771 [1] https://github.com/chenkie/orbit/blob/master/orbit-app/src/App .js