问题
I'm creating an app using CakePHP and have hit a mental barrier when trying to figure out a permission system for the app. I've narrowed it down to a couple different methods, and I'm looking for some information about which would be a) most easily implemented and b) most efficient (obviously there can be trade-off between these two).
The app has many different models, but for simplification I'll just use User, Department, and Event. I want to be able to individually control CRUD permissions for each user, on each model.
Cake ACLs
Though poorly documented, I've got somewhat of an idea of how the ACL system works, and considered creating AROs as follows:
[1]user
create
read
update
delete
[2]department
...
etc. This would require users being in many different groups, and from what I've seen, Cake doesn't easily support this. Is there possibly a better way to do this, or is ACL not suitable for this situation?
Permission Flags in DB
This one is pretty straightforward, obviously having a flag in the user's record for
create_users
, read_users
, etc. With 4-5 models, this would mean 16-20 fields for permissions, which made me consider either using bit masks, or using a joined table. Is one of these better than the other? Which one is faster with less overhead?
Overall, I guess I really want to know what approach makes the most sense in the scale of the application from an efficiency and ease-of-development standpoint. I'm also open to other suggestions of how to go about this, if you have experience from a past project. Thanks in advance!
回答1:
This is generally how I set up permissions - you have actions
that can be performed, roles
that can perform those actions
and users
who have roles
. The examples I've put here are based on what you've requested though I think you'll find it rare you have a user who can do nothing but "create new user records" or "update department records".
actions
id varchar(50)
description varchar(200)
+-------------------+----------------------------------------------+
| id | description |
+-------------------+----------------------------------------------+
| USER_CREATE | Allow the user to create USERS records. |
| USER_DELETE | Allow the user to delete USERS records. |
| USER_READ | Allow the user to read USERS records. |
| USER_UPDATE | Allow the user to update USERS records. |
| DEPARTMENT_CREATE | Allow the user to create DEPARTMENT records. |
| ................. | ............................................ |
+-------------------+----------------------------------------------+
roles
id unsigned int(P)
description varchar(50)
+----+--------------------+
| id | description |
+----+--------------------+
| 1 | Manage users |
| 2 | Manage departments |
| .. | .................. |
+----+--------------------+
roles_actions
id unsigned int(P)
role_id unsigned int(F roles.id)
action_id varchar(50)(F actions.id)
+----+---------+-------------------+
| id | role_id | action_id |
+----+---------+-------------------+
| 1 | 1 | USER_CREATE |
| 2 | 1 | USER_DELETE |
| 3 | 1 | USER_READ |
| 4 | 1 | USER_UPDATE |
| 5 | 2 | DEPARTMENT_CREATE |
| 6 | 2 | DEPARTMENT_DELETE |
| .. | ....... | ................. |
+----+---------+-------------------+
users
id unsigned int(P)
username varchar(32)(U)
password varchar(123) // Hashed, like my potatoes
...
+----+----------+----------+-----+
| id | username | password | ... |
+----+----------+----------+-----+
| 1 | bob | ******** | ... |
| 2 | april | ******** | ... |
| 3 | grant | ******** | ... |
| .. | ........ | ........ | ... |
+----+----------+----------+-----+
users_roles
id unsigned int(P)
user_id unsigned int(F users.id)
role_id unsigned int(F roles.id)
+----+---------+---------+
| id | user_id | role_id |
+----+---------+---------+
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| .. | ....... | ....... |
+----+---------+---------+
To determine if a user has a particular permission you could execute a query like this:
SELECT COUNT( roles_actions.id )
FROM users
LEFT JOIN users_roles ON users.id = users_roles.user_id
LEFT JOIN roles_actions ON users_roles.role_id = roles_actions.role_id
WHERE roles_actions.action_id = '<action.id>'
来源:https://stackoverflow.com/questions/19457513/most-efficient-easy-method-for-permission-system