问题描述
我有一个带有 customroutes 和资源(比如 /users)的 react 管理应用程序。我的自定义路由之一是一个私有页面(比如 /private),我用 useAuthenticated() 钩子保护它:
export default () => {
useAuthenticated();
return (<Card>
<Title title="Private Page" />
<CardContent>
This is a private page.
</CardContent>
</Card>)
}
当我浏览此私人页面但未通过身份验证时,我正在按原样进入身份验证过程(我使用的是 OIDC)。此过程由 authProvider 的 checkAuth() 方法触发。但是当这个过程完成时,我被重定向到 /users 资源而不是 /private 页面。有没有办法告诉 authProvider 我想被重定向到私人页面?
谢谢 - C
解决方法
我自己没有这样做,但我想您可以使用重定向路径作为 useAuthenticated() 调用中的参数。 https://marmelab.com/react-admin/Authentication.html#useauthenticated-hook
export default () => {
useAuthenticated({ redirectPath: '/privatepage' });
return (
<Card>
<Title title="Private Page" />
<CardContent>
This is a private page.
</CardContent>
</Card>
)
}
从那里你应该能够在你的 checkAuth 方法中使用那个 arg/参数。
,tl;dr 在你的 login().then() 方面,做一个重定向('/myDefaultUrl')
我想我和你有同样的挑战。在稍微查看 ReactAdmin 代码后,我无法找到一种以任何“官方”方式进行操作的方法。我确实在 useAuthProvider() 钩子中看到了一些非常有趣的东西。
由 RA 维护的 AuthProvider 对象似乎有一个变量,其中包含一些用一些默认值初始化的属性。
import { useContext } from 'react';
import { AuthProvider } from '../types';
import AuthContext from './AuthContext';
export const defaultAuthParams = {
loginUrl: '/login',afterLoginUrl: '/',};
/**
* Get the authProvider stored in the context
*/
const useAuthProvider = (): AuthProvider => useContext(AuthContext);
export default useAuthProvider;
特别是 afterLoginUrl 属性看起来很有趣。我试图在我的 authProvider 中覆盖该属性,但没有任何运气。
我最终做的是这个。在我调用登录名(来自 useLogin())时,当 authProvider.login 解析时,我将用户及其个人资料返回(我使用 Cognito,因此它是一个 CognitoUser 实例)。在我的用户中,我配置了用户登录后应该去哪里的属性。然后我简单地使用重定向钩子(来自 useRedirect)然后将用户定向到该 URL。
这是我从我的 AuthProvider 登录的:
const authProvider = {
login: (params) => {
if (params instanceof CognitoUser) {
return params;
}
if (params.error) {
return Promise.reject(params.error);
}
return new Promise((resolve,reject) => {
Auth.signIn(params.username,params.password).then(cognitoUser => {
if (cognitoUser.challengeName === 'NEW_PASSWORD_REQUIRED') {
reject({ code: 'NewPasswordRequired',cognitoUser: cognitoUser })
} else {
setAndStoreUserProfile(cognitoUser);
resolve(cognitoUser);
}
},function(err) {
reject(err);
});
});
},....
然后在我的登录表单中,我这样做:
raLogin(formData)
.then((cognitoUser) => {
console.log("User logged in. Result:",cognitoUser);
clearTransitionState();
redirect('/profile');
})
.catch(error => {
if (error.code && error.code === 'PasswordResetRequiredException') {
transition(PHASE.RESET_ACCOUNT,{username: formData.username });
} else if (error.code && error.code === 'NewPasswordRequired') {
transition(PHASE.NEW_PASSWORD,{ cognitoUser: error.cognitoUser });
} else {
processAuthError(error);
}
});