Conventional solution for the visitors + AclComponent
At different places where I read about ACL, a common question that always comes early in the comments is:
Assuming ‘Guests’ users are unidentified web visitors, how do you handler their access rights? They don’t login, so they can’t be assigned an ARO and thus ACL will reject their access to any actions.
How do you handle ‘Guest’ user’s permissons if they are not logged in?The popular solution:
[…] create a PUBLIC Aro with all the base permissions and then have an AppController::beforeFilter […]
I treat any user who does not have a user id to be a guest. By this what I mean is that whenever a user logs-in, I create a session variable with the userId and check it in the beforeFilter method of the controller. So if I do not find the userId in the session, it means that the user is a guest!As you can see, both will require some configuration; creating the ‘guest’ ARO and related ACOs.
After fully implementing the AclComponent and optimizing it’s queries, I also realized that not only does it require configuration but it also bombards your database with queries for every action performed by the guest. At a minimum, 2 queries are required - multiply that by the number of nodes deep the ACO is and the number of concurrent guests on your site, doesn’t scale correctly, does it?
My solution is just a couple lines in the beforeFilter and a new convention:
if (preg_match('/^(public|display$)/', $this->action))
{
$this->Auth->allow();
}
Here, I check if the requested action name starts with ‘public’ or is ‘display’, if it returns true, I allow the action and by-pass the useless SQL queries. Obviously, the convention is to prepend ‘public’ to the name of all actions that are supposed to be accessible guests.
I prefer this solution not only because it optimizes performance another bit, but it’s also shorter in terms of lines of code and is in line with the ‘convention over configuration’ spirit. I’d be curious to know how others are treating visitors… anyone?
October 29th, 2007 at 6:23 am
This is a very elegant solution, and I like the convention over configuration as well.
I think that this method for simple group based access may be much more efficent than ACL as it removes a ton of DB queries.
Geoff
October 29th, 2007 at 8:45 am
Thanks for dropping by Geoff. This definitely saves lots of queries, I am going to be use it for ‘visitors’ and ’subscribers’, both part of parent ‘Guests’ but with a couple different permissions.
Jad
February 23rd, 2008 at 6:25 am
wow! thanks for this insightful post
February 27th, 2008 at 2:16 pm
hi, just been reading through some of your excellent cake posts. This is a nice idea, and you cuold possibly add to the convention side of it by setting a Config::write() directive of the prefix to look for in the regex, so it behaves a little more like the admin routing (where you can prepend whatever prefix you choose).
thanks a lot for your blog - liked the validation section very much too, it was helpful. Had you thought of adding some of the content to the Cake Book (wiki thing) now?