Restricting access with permissions
I've set user permissions in Firebase using "setCustomUserClaims" and "authProvider.getPermissions()" returns the permissions array I've set. However, restricting access to resources or views are not working:
https://marmelab.com/react-admin/Authorization.html
<Admin
dataProvider={dataProvider}
authProvider={authProvider}
>
{permissions => [
// Restrict access to the edit and remove views to admin only (tried "permissions.includes('admin')" as well)
<Resource
name="customers"
list={VisitorList}
edit={permissions === 'admin' ? VisitorEdit : null}
icon={VisitorIcon}
/>,
// Only include the categories resource for admin users (tried "permissions.includes('admin')" as well)
permissions === 'admin'
? <Resource name="categories" list={CategoryList} edit={CategoryEdit} icon={CategoryIcon} />
: null,
]}
</Admin>
Better yet, it would be great to block login completely based on permissions i.e. only admin is able to log in
Hi @yusrimathews,
The way permissions is set up is as an Array of claims so try using
permissions.includes('admin')
Restricting Login
As discussed in #140, you can wrap the authProvider, so that it require's that the user has the 'admin' claim set (as shown below).
const authProvider = FirebaseAuthProvider(firebaseConfig, options);
const dataProvider = FirebaseDataProvider(firebaseConfig, options);
// Use this just like the normal auth provider
const myAuthProvider = {
// Copy all authprovider functionality
...authProvider,
// Wrap the login and check for custom claims
login: async (params) => {
const user = await authProvider.login(params);
// getPermissions is how when get the custom claims for the logged in user
const claims = await authProvider.getPermissions();
const isAdmin = Array.isArray(claims) && claims.includes("admin");
if (isAdmin) {
return user;
}
// Make sure user is logged out, if not an admin
await authProvider.logout()
throw new Error("Login error, invalid permissions");
},
};
Cheers, Ben
Thanks @benwinding 🥇
Using firebase v8.7.x, the above worked for me with a few small tweaks:
// ...
const { scope } = await authProvider.getPermissions(); // get claims.scope
// scope looks something like ["USER", "ADMIN"]
return Array.isArray(scope) && scope.includes('ADMIN');
// ...