如何在 react-admin 的 AuthProvider 中配置 getPermissions() 方法?



我尝试创建自定义钩子来调用 DataProvidergetOne()方法,以根据登录后从 authProvider 获得的用户名获取权限,但是从函数主体调用钩子的持续要求会引发错误,因为我从方法调用它。

权限从何而来?"ra-core"如何称呼这个getPermissions()?为什么在getPermissions()中有一个错误叫做.then()而不是函数?

需要有关于AuthProvider这方面的更好的文档,以帮助即使是经验丰富的反应管理员。只是说。

钩子获取权限:

const useFetchPermissions = ({ emailId }) => {
const dataProvider = useDataProvider();
const [loading, setLoading] = useState(true);
const [error, setError] = useState();
console.log("fetching permissions");
const [permissions, setPermissions] = useState();
useEffect(() => {
dataProvider
.getOne("users/permissions", { id: emailId })
.then(({ data }) => {
setPermissions(data);
setLoading(false);
})
.catch((error) => {
setError(error);
setLoading(false);
});
}, []);
if (loading) return <Loading />;
if (error) return <Error />;
if (!permissions) return null;
return permissions;
};

身份验证登录方法:

login: () => {
/* ... */
console.log("Logging in..");
//localStorage.setItem("permissions", "CREATE_ITEM");
return tfsAuthProvider.login();

AuthProvider getPermissions方法:

getPermissions: () => {
const role = localStorage.getItem("permissions");
console.log(role);
//useFetchPermissions(authProvider.getAccount().userName); throw error
return role === null ? Promise.resolve() : role;
},

App.js dataProvider(url,useHttpClient) 调用以下内容:

const useHttpClient = (url, options = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: "application/json" });
}
// add your own headers here
//options.headers.set("Access-Control-Allow-Origin", "true");
//const token = localStorage.getItem("token");
//const userName = authProvider.getAccount().userName;
//const [permissions, setPermissions] = useState();
//const permissions = useFetchPermissions(userName);  throws error
//localStorage.setItem("permissions", permissions);
options.headers.set(
"Authorization",
`Bearer ${authProvider.getAccount().userName}`
);
return fetchUtils.fetchJson(url, options);
};

如果用户权限仅基于用户会话中不会更改的emailId,为什么每次都调用 API 以获取用户权限?

我会在authProviderlogin方法中进行调用,您有两种选择:

  1. 取决于 API 和后端,您可以(如果有选择)在复杂的 json 对象或 jwt 中返回权限以及login时的其他用户信息。

  2. 根据emailId并在成功登录响应后,进行连续调用(如useFetchPermissions中的上述调用),并再次将它们存储在稍后可以访问它们的地方getPermissions().

我没有测试过这段代码,所以它可能会有一些错误,但只是想如何在没有钩子的情况下构建登录管道。

login: () => {
console.log("Logging in..");

tfsAuthProvider
.login() 
.then(response => {
if (response.status < 200 || response.status >= 300) {              
throw new Error(response.statusText);
}
return response.json();
})
.then(({ emailId }) => (
dataProvider.getOne("users/permissions", { id: emailId })
))
.then(({ data }) => {
const permissionsString = JSON.stringify(permissions);
// store wherever you want
localStorage.setItem(userPermissionsKey, permissionsString);                                  
})
.catch((error) => {
throw new Error(error);                
});
}

多亏了@KiaKaha的回答,我能够实现一些对我有用的东西,这是解决 react-hooks 异常的解决方法。

编辑:这是一个改进的解决方案

login: () => {
/* ... */
console.log("Logging in..");
console.log(tfsAuthProvider.authenticationState);

return tfsAuthProvider.login().then(async () => {
const result = await fetch(
process.env.REACT_APP_BASE_URL +
"/users/permissions/" +
tfsAuthProvider.getAccount().userName
);

const body = await result.json();
console.log(body);
localStorage.setItem("permissions", body);
return Promise.resolve();
});

},
  1. dataProvider.getOne()方法是一个反应钩子,因此我无法调用它。所以用fetch().使用环境变量来获取数据提供程序使用的 URL。(这仍然是正确的)。

<->-

  1. response无法直接转换为字符串,所以我使用response.body.getReader()和 UTF8 解码器解码read()的结果。

    login: () => {
    console.log("Logging in..");
    console.log(tfsAuthProvider.authenticationState);
    const utf8Decoder = new TextDecoder("utf-8");
    return tfsAuthProvider
    .login()
    .then(() =>
    fetch(
    new Request(
    process.env.REACT_APP_BASE_URL +
    "/users/permissions/" +
    tfsAuthProvider.getAccount().userName,
    {
    method: "GET",
    headers: new Headers({ "Content-Type": "application/json" }),
    }
    )
    )
    )
    .then((response) => {
    if (response.status < 200 || response.status >= 300) {
    throw new Error(response.statusText);
    }
    return response.body.getReader();
    })
    .then((reader) => reader.read())
    .then(({ done, value }) => {
    // if (done) {
    //   controller.close();
    //   return;
    // }
    const permissions = utf8Decoder.decode(value);
    console.log(permissions);
    localStorage.setItem("permissions", permissions);
    return Promise.resolve();
    });
    },
    

希望这能帮助任何通过这个兔子洞的人。

有关可读流对象的更多信息 - https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams

有关登录实现的更多信息 - https://marmelab.com/react-admin/Authorization.html

相关内容

  • 没有找到相关文章

最新更新