基于aor-permissions(admin-on-rest权限)的已有项目权限问题咨询
Hey there! Let's break down how to integrate aor-permissions into your existing project, working alongside your current token-based auth setup.
First, Quick Recap of Your Current Setup
You've got a hasAuth function that checks for a valid token in your Redux store to protect routes. We'll extend this to add permission checks, plus cover component-level permission control too.
Step 1: Ensure Permissions Are Stored in Redux
First, you need to track user permissions/roles in your store alongside the token. When a user logs in, fetch their permissions from your backend (along with the token) and save them to a reducer (e.g., permissionReducer). For example:
// Example login success action const loginSuccess = (token, roles) => ({ type: 'LOGIN_SUCCESS', payload: { token, roles } }); // In your permissionReducer const initialState = { roles: [] }; export default function permissionReducer(state = initialState, action) { switch (action.type) { case 'LOGIN_SUCCESS': return { ...state, roles: action.payload.roles }; default: return state; } }
Step 2: Extend Route Auth Checks with Permissions
Modify your existing hasAuth function to validate permissions after confirming the user has a valid token. We'll use aor-permissions's built-in checkPermissions utility for this:
import { checkPermissions } from 'aor-permissions'; function getRoutes(store) { function hasAuth(nextState, replace, callback){ const state = store.getState(); const hasToken = !!state.tokenReducer.token; debug('AUTH: ', hasToken) // First, check if user is logged in if (!hasToken){ replace('/login'); return callback(); } // Now check if user has required permissions for the route const userRoles = state.permissionReducer.roles; // Assume your route config has a `permissions` field (e.g., { path: '/dashboard', permissions: ['admin'] }) const requiredPermissions = nextState.routes[0].permissions; // Use aor-permissions to validate const hasAccess = checkPermissions(userRoles, requiredPermissions); if (!hasAccess) { replace('/unauthorized'); // Redirect to a custom "no access" page debug('AUTH: User lacks permissions for this route'); } callback(); } // Example route config with permissions return ( <Route path="/" component={App}> <Route path="login" component={Login} /> <Route path="dashboard" component={Dashboard} onEnter={hasAuth} permissions={['admin']} /> <Route path="posts" component={Posts} onEnter={hasAuth} permissions={['admin', 'editor']} /> <Route path="unauthorized" component={Unauthorized} /> </Route> ); }
Step 3: Component-Level Permission Control
For hiding/showing specific UI elements (like buttons or sections) based on permissions, use aor-permissions's <Permissions> component:
import { Permissions } from 'aor-permissions'; import { List, Datagrid, TextField, DeleteButton, EditButton } from 'react-admin'; const PostList = (props) => ( <List {...props}> <Datagrid> <TextField source="title" /> {/* Only admins can see the Delete button */} <Permissions permissions="admin"> <DeleteButton /> </Permissions> {/* Admins OR editors can see the Edit button */} <Permissions permissions={['admin', 'editor']}> <EditButton /> </Permissions> </Datagrid> </List> );
Pro Tip: Configure Permission Source
If your permissions aren't stored in the default state.admin.permissions path, tell aor-permissions where to find them by setting up the provider in your <Admin> component:
import { Admin } from 'react-admin'; import { permissionsProvider } from 'aor-permissions'; const App = () => ( <Admin dataProvider={yourDataProvider} authProvider={yourAuthProvider} customReducers={{ permissionReducer }} // Point to your permission storage in Redux {...permissionsProvider({ permissionSelector: state => state.permissionReducer.roles })} > {/* Register your resources here */} </Admin> );
Step 4: Custom Permission Logic (If Needed)
If the default checkPermissions doesn't fit your use case (e.g., you need granular permission checks instead of roles), create a custom validator:
const customPermissionCheck = (userPermissions, requiredPermissions) => { // Example: userPermissions is an object like { canEditPosts: true, canDeletePosts: false } return requiredPermissions.every(perm => userPermissions[perm]); }; // Use in route checks if (!customPermissionCheck(userPermissions, requiredPermissions)) { replace('/unauthorized'); } // Or in components <Permissions permissions={['canEditPosts']} checkPermissions={customPermissionCheck} > <EditButton /> </Permissions>
Key Things to Remember
- Always fetch and store user permissions when they log in—don't rely on client-side only checks (validate permissions on the backend too!).
- Test with different user roles/permissions to make sure routes and UI elements lock down correctly.
- If you're using
react-admin, ensure yourauthProviderworks alongside the permission setup to avoid conflicts.
内容的提问来源于stack exchange,提问作者EdG

