我正在使用from api.api import app
from flask_script import Manager
from api.connector import engine, BaseModel
from api.detector.route import Detector
manager = Manager(app)
app.config['DEBUG'] = True
@manager.command
def create_tables():
"Create relational database tables."
BaseModel.metadata.create_all(engine)
if __name__ == '__main__':
manager.run()
保护整个应用程序。所有路由均受ProtectedRoute组件(请参见下面的代码)保护,该组件将重定向到外部URL,如果用户未登录,则为单点登录(SSO)页面。
当用户转到“ / home”时,在获得重定向到“ external-login-page.com /”(登录页面)之前,他们会简要了解(受保护的)路由。如何避免闪烁,以便用户仅看到登录页面?
react-router-dom
答案 0 :(得分:2)
window.location.href
以防止闪烁。同样,在您的特定情况下,您可能想要的是在未验证用户身份时完全不呈现任何内容。
代码可能看起来像这样:
export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({
isAuthenticated,
...rest
}) => {
if (!isAuthenticated) { // redirect if not logged in
window.location.href = 'http://external-login-page.com/';
return null;
} else {
return <Route {...rest} />;
}
};
答案 1 :(得分:1)
您可以考虑使用Redirect组件
export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({
isAuthenticated,
...rest
}) => {
if (!isAuthenticated) {
return <Redirect to='https://external-login-page.com/' />
} else {
return <Route {...rest} />;
}
};
我猜想直接调用window
+ return null
会在页面重新加载之前一瞬间渲染React应用。
答案 2 :(得分:1)
您可以像这样简单地使用重定向组件。
export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({
isAuthenticated,
children,
...rest
}) => {
return <Route {...rest} render={() => isAuthenticated ? children : <Redirect to='http://external-login-page.com/' />}
}
答案 3 :(得分:0)
发布最终适用于我的解决方案:而不是被Router
阻止,而被App
阻止。
关键是将App
分成两个部分,AuthenticatedApp
和UnauthenticatedApp
。从那里,根据用户的访问级别,延迟加载正确的组件。这样,如果没有获得授权,他们的浏览器甚至根本不会加载AuthenticatedApp
。
AuthenticatedApp
是整个应用程序,提供程序,路由器等的组成部分。无论您最初在App.tsx中拥有什么,都应该放在这里。UnauthenticatedApp
是一个组件,您希望用户在不允许他们访问应用程序时看到它们。诸如“未经授权。请与管理员联系以寻求帮助。” App.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;
在[0]上阅读Kent C Dodd的精彩文章!
编辑:用相似的方法找到了另一个很好的例子,有点复杂-[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