React-Admin对资源的权限



我对React Admin的资源权限有一个问题。我想隐藏一些具有特定用户角色的资源,使用通过登录获得的JWT中的角色数组。

这是认证的authProvider

import decodeJwt from 'jwt-decode';
export default {
login: ({ username, password }) => {
const request = new Request('http://myresource.org', {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
return fetch(request)
.then(response => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
}
return response.json();
})
.then(({ token }) => {
const decodedToken = decodeJwt(token);
localStorage.setItem('token', token);
localStorage.setItem('permissions', JSON.stringify(decodedToken.roles));
});
},

logout: () => {
localStorage.removeItem('token');
localStorage.removeItem('permissions');
return Promise.resolve();
},

checkError: error => {
},

checkAuth: () => {
return localStorage.getItem('token') ? Promise.resolve() : Promise.reject();
},

getPermissions: () => {
const roles = localStorage.getItem('permissions');
console.log(roles);    //This print correctly the array
return roles ? Promise.resolve(JSON.parse(roles)) : Promise.reject();
}
};

这是主应用

import * as React from "react";
import { Admin, Resource, resolveBrowserLocale } from 'react-admin';
import Dashboard from './Dashboard';
/*** Import Lingue ***/ 
import polyglotI18nProvider from 'ra-i18n-polyglot';
import englishMessages from 'ra-language-english';
import italianMessages from 'ra-language-italian';
import * as resources_IT from './translations/Resources_IT';
/*** Import Grafici ***/ 
import UserIcon from '@material-ui/icons/Group';
import HotelIcon from '@material-ui/icons/Hotel';
import BookingIcon from '@material-ui/icons/MenuBook';
import DeviceIcon from '@material-ui/icons/DeviceHub';
import CustomerIcon from '@material-ui/icons/EmojiPeople';
import DeviceAccountIcon from '@material-ui/icons/AccountBox';
/*** Import Providers ***/ 
import dataProvider from './providers/DataProvider';
import authProvider from './providers/AuthProvider';
/*** Import Resources ***/ 
import { HotelList, HotelEdit, HotelCreate } from './resources/Hotel';
import { DeviceList, DeviceEdit, DeviceCreate } from './resources/Device';
import { UserList, UserEdit, UserCreate, UserShow } from './resources/User';
import { BookingList, BookingEdit, BookingCreate } from './resources/Booking';
import { CustomerList, CustomerEdit, CustomerCreate } from './resources/Customer';
import { DeviceAccountList, DeviceAccountEdit, DeviceAccountCreate } from './resources/DeviceAccount';

/* Configurazione della lingua del Browser */
const messages = {
it: { ...italianMessages, ...resources_IT },
en: englishMessages,
};
const i18nProvider = polyglotI18nProvider(
locale => messages[locale] ? messages[locale] : messages.en, resolveBrowserLocale()
);

const App = () => (
<Admin dashboard={Dashboard} dataProvider={dataProvider} i18nProvider={i18nProvider} authProvider={authProvider}>
{permissions => [
permissions.indexOf('SYSADM') >= 0 ? (<Resource name="hotels" list={HotelList} edit={HotelEdit} create={HotelCreate} icon={HotelIcon} />) : null,
]}
<Resource name="roles" />
<Resource name="users" list={UserList} edit={UserEdit} create={UserCreate} icon={UserIcon} />
<Resource name="devices" list={DeviceList} edit={DeviceEdit} create={DeviceCreate} icon={DeviceIcon} />
<Resource name="bookings" list={BookingList} edit={BookingEdit} create={BookingCreate} icon={BookingIcon} />
<Resource name="customers" list={CustomerList} edit={CustomerEdit} create={CustomerCreate} icon={CustomerIcon} />
<Resource name="deviceaccounts" list={DeviceAccountList} edit={DeviceAccountEdit} create={DeviceAccountCreate} icon={DeviceAccountIcon} />
</Admin>
);
export default App;
最后,这是JWT:
{
"aud": "backoffice-fe",
"sub": "email@test.com",
"idHotels": [
"21816730-a4ef-4fea-8fb9-adc019d80485"
],
"roles": [
"SYSADM"
],
"iss": "backoffice-api"
}

似乎app.js中的permissions没有正确获得。有人知道怎么解吗?

文档示例:

https://marmelab.com/react-admin/Permissions.html restricting-access-to-resources-or-views

适合我。只要确保:

const { loading, permissions } = usePermissions();

return loading
? (<div>Waiting for permissions...</div>)
: (
<>
(your admin...)

最后像在文档中一样:

{permissions => [
// Restrict access to the edit and remove views to admin only
<Resource
name="customers"
list={VisitorList}
edit={permissions === 'admin' ? VisitorEdit : null}
icon={VisitorIcon}
/>,
// Only include the categories resource for admin users
permissions === 'admin'
? <Resource name="categories" list={CategoryList} edit={CategoryEdit} icon={CategoryIcon} />
: null,
]}

ps:要做到这一点,你必须使用一个函数作为唯一的子函数。

如果您想添加多个子元素,则将它们包含在<>

{permissions => [
// Restrict access to the edit and remove views to admin only
<Resource
name="customers"
list={VisitorList}
edit={permissions === 'admin' ? VisitorEdit : null}
icon={VisitorIcon}
/>,
// Only include the categories resource for admin users
permissions === 'admin'
? <>
<Resource name="posts" list={PostList} edit={PostEdit} icon={PostIcon} />
<Resource name="categories" list={CategoryList} edit={CategoryEdit} icon={CategoryIcon} />
</>
: null,
]}

最新更新