Thoughts about Yii authentication and authorization

I have been thinking - with the current user authentication/authorization - when a user logs in they have a session/cookie made with their user id and any other information you specify. However, is this the best way?

Would it be better that when a user logs in, a unique token is allocated to the user and is stored in the database as well as in a cookie along with just a user id. And then each time a user comes onto the site, the cookie is read, and the token is then checked against the database with user id (maybe an onbeginrequest event handler could handle this). And if it is valid then user remains logged in. However, the difference is, with this method you are also able to load relavent up to date user data. Since with the current method, certain user data is only loaded into the cookie at the point of logging in. Therefore, if a user was to be banned between the time of them exiting the site and coming back on, it would still be noted in their cookie that they were not banned since the data was only true at the time of logging in.

Input on this would be great!

I was thinking on this lately as well, thanks for letting this to surface.

Since I use db-backed notification system, I had to extend CWebUser and apart from many changes I also overrode restoreFromCookie().

This is useful to reestablish user’s permissions and throw http 403 if necessary (i.e. the user has been banned).

I’d also love to see some other changes to this aspect of Yii, like IP/useragent matching capability and storing states not in cookies but somewhere else.

A quick note to Qiang about the reasons: many developers tend to ignore optimization techniques, therefore a quite high amount of http requests can be initialized for a single pageview. Furthermore, if static content is also stored under the same domain, all cokies will be sent along with the requested filename, without any need.

If a cookie exceeds 1kb in size, even 20-50 (or even more) kilobytes cookie data can be sent completely unnecessarily, which is a total waste for a single pageview. Not to mention if the cookie gets filled with all kinds of states and flashes.

If it’s possible, I rather choose a cookiesize with about 130 bytes (s=md5(…)).

There is this note in the documentation:

[indent]

Note, when allowAutoLogin (cookie-based authentication) is enabled,

all these persistent data (setState/getState) will be stored in cookie. Therefore, do not

store password or other sensitive data in the persistent storage. Instead,

you should store them directly in session on the server side if needed.

[/indent]

You could disable autologin or always save your persistent data directly in the session, the cookie will then only contain the sessionID.

Furthermore you can configure Yii so that session data is saved in a database, just add this to your config file in the components section:




'session'=array(

    'class'=>'CDbHttpSession',

),



You could write your own class MyCDbHttpSession that extends CDbHTTPSession to also save the userID along with the session data, so you could explicitly logout a user when you changed his permissions. I think this is a better way than to read all user permissions for every request.

Ah, yes, I have session installed, just confirmed what you’ve said. Sorry I remembered wrongly. :mellow:

Still, I think my above comment contains good stuff for newbie developers, so I just leave that for now.

Another problem is if you have a lot of states saved, then the cookies can become really big and even cause apache to get errors like in my case

What if I save the session data in the database (using config ‘class’=>‘CDbHttpSession’), use “allowAutoLogin” and set some states ($this->setState) in the UserIdentity? Will this data be stored in the database or in the cookies?

Thank you!

Ok, answering my own question. The data will be stored both in the database and in the cookies. Now the question is how to keep this data in the database, but not in the cookie?