PHP页面级角色权限系统设计逻辑咨询
Hey there! Let's work through your questions and refine your permission system step by step.
1. Access to /remove-user/{user_id} with /remove-user Permission
With your current setup, the answer is no—since your pages table stores exact page_link values, the system will only match the exact string /remove-user, not its dynamic subpaths like /remove-user/123.
To fix this, you have two practical approaches:
- Prefix Matching: Store the parent path as
/remove-userinpage_link, then check if the current URL starts with this prefix. For example, in code:# Example in Python current_url = "/remove-user/123" allowed_prefixes = ["/remove-user"] if any(current_url.startswith(prefix) for prefix in allowed_prefixes): # Grant access - Wildcard/Regex Matching: Store patterns like
/remove-user/*inpage_link, then convert the wildcard to a regex (e.g.,^/remove-user/.*$) and test the current URL against it for a match.
2. Handling Page-Specific Function Permissions
Your idea of adding a dedicated table for functions is totally valid, and it's a standard way to implement fine-grained, action-level permissions. Here's how to refine this approach:
- Recommended Table Structure: Create a
function_permissionstable with these columns:id(auto-increment primary key)role_id(foreign key linking toroles.id)function_key(unique identifier likeuser.delete,user.ban,post.edit)page_id(optional foreign key topages.id—to tie the function to a specific page)
- Frontend Control: When rendering a page (e.g., user management), fetch all allowed
function_keyvalues for the user's role, then conditionally show/hide buttons. For example: only display the "Delete User" button ifuser.deleteis in the user's allowed functions. - Critical Backend Validation: Never rely solely on frontend hiding—always validate permissions in your backend handlers. For example, when a delete request comes in, first check if the user's role has the
user.deletepermission before executing any database changes.
Alternatively, you could extend your existing permissions table to include a function_key column, but a separate table keeps your data model cleaner as your system scales.
3. Simplified Implementation Tips
Your current RBAC (Role-Based Access Control) structure is solid, but here are ways to streamline it for maintainability:
- Combine Database Queries: Instead of multiple separate calls, use JOINs to fetch all allowed page links in one query. Example SQL:
SELECT p.page_link FROM users u JOIN roles r ON u.userlevel = r.id JOIN permissions pm ON r.id = pm.role_id JOIN pages p ON pm.page_id = p.id WHERE u.username = 'current_logged_in_user'; - Cache Permissions: After a user logs in, store their allowed page links and function permissions in a session (or Redis for distributed systems). This cuts down on repeated database hits for every page load.
- Use Permission Groups: For common permission bundles (e.g., "full user management" includes
user.view,user.edit,user.delete), create apermission_groupstable to assign multiple permissions to a role at once—avoiding tedious one-by-one entries. - Simplify Path Rules: As noted in question 1, using prefixes or wildcards eliminates the need to add a separate
pagesentry for every dynamic subpath.
Start with the core logic that meets your current needs, then iterate as your project grows—balance flexibility (for future changes) and simplicity (to keep your code easy to debug).
内容的提问来源于stack exchange,提问作者Tiago

