如何在 react-admin 的 AuthProvider 中配置 getPermissions() 方法?
How do I configure the getPermissions() method in the AuthProvider in react-admin?
我已经尝试创建自定义挂钩来调用 DataProvider getOne()
方法,以根据登录后从 authProvider 获得的用户名获取权限,但始终需要从函数抛出错误,因为我从方法中调用它。
权限从何而来? 'ra-core' 怎么称呼这个 getPermissions()
?为什么有一个名为 .then()
的错误不是 getPermissions() 中的函数?
在 AuthProvider 的这方面需要更好的文档来帮助甚至有经验的 react-admin 人员。只是说.
获取权限的挂钩:
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;
};
AuthPProvider 登录方式:
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);
};
为什么每次都调用 API 来获取用户权限,如果它们仅基于 emailId
而在整个用户会话期间都不会更改?
我会在 authProvider
的 login
方法中调用,您有两个选择:
取决于 API 和后端,您可以(如果您有选择)return 复杂 json 对象或内部的权限jwt 以及 login
.
上的其他用户信息
基于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();
});
},
dataProvider.getOne()
方法是 react-hook,因此我无法调用它。所以用了fetch()
。使用环境变量获取 dataProvider 使用的 URL。 (这仍然是正确的)。
<-- 这之后的一切都是不必要的,可能有助于解决其他问题。-->
response
不能直接转成字符串所以我用response.body.getReader()
和UTF8解码器解码read()
.[=19=的结果]
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
我已经尝试创建自定义挂钩来调用 DataProvider getOne()
方法,以根据登录后从 authProvider 获得的用户名获取权限,但始终需要从函数抛出错误,因为我从方法中调用它。
权限从何而来? 'ra-core' 怎么称呼这个 getPermissions()
?为什么有一个名为 .then()
的错误不是 getPermissions() 中的函数?
在 AuthProvider 的这方面需要更好的文档来帮助甚至有经验的 react-admin 人员。只是说.
获取权限的挂钩:
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;
};
AuthPProvider 登录方式:
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);
};
为什么每次都调用 API 来获取用户权限,如果它们仅基于 emailId
而在整个用户会话期间都不会更改?
我会在 authProvider
的 login
方法中调用,您有两个选择:
取决于 API 和后端,您可以(如果您有选择)return 复杂 json 对象或内部的权限jwt 以及
上的其他用户信息login
.基于
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();
});
},
dataProvider.getOne()
方法是 react-hook,因此我无法调用它。所以用了fetch()
。使用环境变量获取 dataProvider 使用的 URL。 (这仍然是正确的)。
<-- 这之后的一切都是不必要的,可能有助于解决其他问题。-->
response
不能直接转成字符串所以我用response.body.getReader()
和UTF8解码器解码read()
.[=19=的结果]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