What you’ll want to do to create a cookie is create a new object of type CHttpCookie: Yii’s class for cookies. Here, then, is the syntax for setting a cookie in Yii:
Yii::app()->request->cookies['name'] = new CHttpCookie('name', 'value');
You must use the same name value in both places, replacing it with the actual cookie name. Remember that the cookie’s name, and value, are visible to users in their browsers, so one ought to be prudent about what name you use and be extra mindful of what values are being stored.
Tip: Because the cookie’s name must be used twice in the code, you may want to consider assigning the cookie’s name to a variable that is used in both instances instead.
To test if a cookie exists, just use isset() on Yii::app()->request->cookies[‘name’], as you would any other variable.
To delete an existing cookie, just unset the element as you would any array element:
To delete all existing cookies (for that site), use
By default, cookies will be set to expire when the browser window is closed. To change that, you need to modify the properties of the cookie. You can’t do so when you create the CHttpCookie object (i.e., the only arguments to the constructor are the cookie’s name and value), so you must separately create a new object of type CHttpCookie, to be assigned to Yii::app()->request->cookies later:
$cookie = new CHttpCookie('name', 'value');
Then adjust the expire attribute:
$cookie->expire = time() + (60*60*24); // 24 hours
Then add the cookie to the application:
Yii::app()->request->cookies['name'] = $cookie;
You can manipulate other cookie properties using the above syntax: domain, httpOnly, path, and secure. Each of these correspond to the arguments to the setcookie() function. (You can also manipulate the value of the cookie through $cookie->value and the cookie’s name through $cookie->name). For example, if you want to limit a cookie to a specific domain, or subdomain, use domain; to limit it to a specific folder, use path; and to only transmit the cookie over SSL, set secure to true.
You can also improve the security of your cookies by setting Yii’s enableCookieValidation to true, in the Yii configuration file:
return array( 'components'=>array( 'request'=>array( 'enableCookieValidation'=>true, ), ), );
Cookie validation prevents cookies from being manipulated in the browser. To accomplish that, Yii stores a hashed representation of the cookie’s value when it gets sent, and then compares the received cookie’s value to ensure they are the same. Obviously there’s extra overhead required to do this, but in some instances, the extra effort is justified by the extra security.
As an example, let’s say that an administrator at your site logs in and does whatever but doesn’t log out. The administrator therefore still has a cookie in her or his browser indicating access to the site (i.e., the user could open the browser and perform admin tasks without logging in again). Now let’s say that the src attribute on malicious site A points to a page on your site that deletes a blog posting. If the administrator with the live cookie loads that page on site A, it will have the same effect as if that administrator went to your site and requested that page directly. This is not good.
To prevent a CSRF attack on your site, first make sure that all significant form submissions use POST instead of GET. You should be using POST for any form that changes server content anyway, but a CSRF POST attack is a bit harder to pull off than a GET attack.
Second, set enableCsrfValidation to true in your configuration file:
return array( 'components'=>array( 'request'=>array( 'enableCsrfValidation'=>true, ), ), );
By doing this, Yii will send a cookie with a unique identifier to the user. All forms will then store that same identifier in a hidden input. The form submission will only be handled then if the two identifiers match. With the case of a CSRF attack, the two identifiers will not match because the form’s identifier will not be passed as part of the request (I hope this is clear; if not, let me know). Note that this only works if you’re using CHtml to create your forms (if you manually create the form tags, Yii won’t insert the necessary code for preventing CSRF attacks).
The most important thing to remember about cookies, which I’ve already stated, is that cookies are visible to the user in the browser. And unless you’re using SSL for the cookies, they are also visible to anyone else while being transmitted back and forth between the server and the client (which happens on every page request). So be careful of what gets stored in a cookie! If the data is particularly sensitive, use sessions instead of cookies.