Skip to main content

skip to main content

developerWorks  >  Open source  >

Cook up Web sites fast with CakePHP, Part 4: Use CakePHP's Session and Request Handler components

Streamline PHP applications

developerWorks
Go to the previous pagePage 3 of 9 Go to the next page

Document options
PDF format - Fits A4 and Letter

PDF - Fits A4 and Letter
221 KB (27 pages)

Get Adobe® Reader®

Sample code


My developerWorks needs you!

Connect to your technical community


Rate this tutorial

Help us improve this content


Session handling

When a request is made for a Web site, it is entirely independent of every request before it. To implement user functionality, a particular Web client needs repeated access to a unique, possibly secret, piece of information. This is called session handling in Web applications, and the subtleties of properly handling sessions is a headache to many developers.

Session-handling basics

The basic idea is the same across any programming language. Upon first visiting the Web site, the client is given a unique ID, generally stored as a cookie. On the server side, an array of variables is stored, in some way, which corresponds to that unique ID. For any subsequent request by the same client, the unique ID is sent along with the request, and the server loads the array into memory. These variables are called the session variables for the client. In PHP, they are stored in the $_SESSION global variable.

You could simply use the $_SESSION global variable to access session information when using CakePHP. However, CakePHP comes with its own session-handling object, which, as we will see later, has a number of benefits.



Back to top


Session handling within Tor

You have already implemented sessions without much effort. When the user logs in, the UsersController object stores the username and associates it automatically with the client during subsequent requests.

Every Controller object (anything inheriting from AppController) automatically has access to the Session component. Recall that a Component is a class associated with a controller that allows extra functionality, much like a helper provides extra functionality to a view. You used the Acl component in Part 2 when you added ACLs. Recall that you needed to add the following line to the beginning of the ProductsController and UsersController classes: var $components = array('Acl');.

Though session handling is a component in CakePHP, it is a standard component included with every controller, so there is no need to add it to this list.

To use the Session component, simply access the session instance variable in the controller. The two most important functions of the session handler are setting and getting variables, which are achieved by calling the read and write methods. For user login, you used the code in Listing 7 to write the current client's username to the session. This code is located in the UsersController class.


Listing 7. Using the write method to store the username
                    
function login()
{
  ...

  $this->Session->write('user', $this->data['User']['username']);

  ...
{
                

The write method takes two parameters. The first is the key being assigned and the second is the value to assign it. In this case, the key is user and the value is the username entered (see Listing 8). The username is later accessed to test whether a product can be viewed or edited based on the ACL.


Listing 8. Using the read method to access the username
                    
function view($id) {
  ...

  if ($this->Acl->check($this->Session->read('user'), 
$id.'-'.$product['Product']['title'], 'read'))
  {
    ...
  }
}
                

The read method takes a single parameter — the key you wish to access — and returns the value that was stored.



Back to top


Storing sessions

None of this should be new to Web developers, but session handling is generally only a simple matter for small applications. If an application requires sensitive user information to be stored in session, such as passwords or credit card information, where and how the data is stored is vitally important.

Session storing is controlled by a single line in CakePHP: Configure::write('Session.save', 'php');. This line, located in the /app/config/core.php file, tells Cake how sessions should be stored. There are three valid values: php (use whatever the php.ini file says), cake (save session files in Cake's tmp directory), and database (use Cake's database sessions).



Back to top


Storing sessions: cake

When this value is set, sessions are stored as files within your application folder. CakePHP provides a folder at /app/tmp/session with files that look something like sess_50bfa744a2ab2c98df808f70c893704c. Within these files, individual session variables are stored as plain text without encryption.

The Apache Web server has a setting called safe mode that restricts the folders Apache has access to. Generally, Apache can only read anything within the docroot of the site, with some exceptions regarding library files. In this series, you have installed CakePHP by dropping the entire directory into Apache's DocumentRoot directory (in this case, the /webroot directory). That's certainly an easy way to install the framework, but it's not the most secure, and this is one reason why. By setting session handling to cake, you are storing session variables in a directory that could be accessed directly by the browser. If your site is compromised in such a way that an attacker can cause Apache to return arbitrary files, every user's session data will be vulnerable (though that might be the least of your worries). Cake does a pretty good job of protecting these files even if everything is in the DocumentRoot, but ideally, you should install more securely by making the app/webroot directory your DocumentRoot directory. This would keep the Cake session files offline.

It is important to note that you cannot control the permissions on these session files. They will have the exact same user and group permissions PHP was granted. On some systems, this may be a security vulnerability, as well.

Advantages:

  • Session variables are stored within Cake, and, thus, the entire application stays in one place.
  • Session files can be read with a text browser, possibly for debugging (unlikely useful).
  • Starting and accessing a session do not require a database connection (unlikely helpful, since accessing models in CakePHP initiates a PHP session).

Disadvantages:

  • Any files stored in DocumentRoot can be compromised if the Web server is compromised.
  • Session files have the same permissions PHP is given.
  • Load-balanced Web servers not sharing a file system cannot share access to session files, causing sessions to be mysteriously dropped unless using sticky sessions.


Back to top


Storing sessions: database

If the session information you are storing needs a higher level of security or a greater control over permissions, database sessions are better. By setting Session_save to database, you're telling CakePHP to store all serialized variable information on a table in the database with the rest of your application.

Before you can use database sessions with CakePHP, you must create the table. Feel free to give it a try with Tor. By default, the name of the table is cake_sessions, although this can be changed in the file app/config/core.php. You will need to uncomment the Configure::write lines for Session.table and Session.database in order to use database session storage. The schema for this table is stored in app/config/sql/sessions.sql. The schema included with CakePHP V1.2.0.x is shown below.


Listing 9. Create table cake_sessions
                    
CREATE TABLE cake_sessions (
  id varchar(255) NOT NULL default '',
  data text,
  expires int(11) default NULL,
  PRIMARY KEY  (id)
);
                

After you've created the table and set the Session.save to database, try logging into Tor at /users/login. After you log in, check the database to see if your session appeared. There should be a single row that looks something like this:

id                                 data                                expires
50bfa744a2ab2c98df808f70c893704c   Config|a:3:{s:4:"rand";i:94427...   1164661678
                

Storing sessions in the database directly addresses all three disadvantages listed in the method above. First, Apache generally has no direct access to the database, so compromising the Web server doesn't expose the session files. Second, permissions on the database can be explicitly set for your application, and you can even restrict access to a particular host. Third, load-balanced servers have shared access to the session table with no extra work on your part.

For most large applications, database sessions are essential because they allow the greatest amount of security with the least amount of effort.

Advantages:

  • Simple to set up — only requires one extra table in your database.
  • A loss of security in the Web server will probably not result in sessions being compromised.
  • Sessions can be more easily shared across load-balanced servers.

Disadvantages:

  • Using the database to store sessions adds some database overhead. That can add up.
  • Sessions are still stored in plain text on the database; database backups may cause sensitive data to be stored for prolonged periods of time.
  • Depending on how your database is set up, communications between your application and the database may not be secure. If your database isn't on localhost, or isn't over a secure channel, such as a VPN, it is possible that the communications can become compromised.


Back to top


Storing sessions: php

The final method for storing sessions is to use whatever session handling PHP is set up to use. By default, PHP will write its sessions as files similar to the cake setting for Session.save. One main difference is that instead of saving session variables within the Cake application, they are generally stored in a temporary directory elsewhere on the file system. This may or may not be preferable to having sessions stored in the same directory as your site.

By setting sessions to be stored via PHP, you are giving more control over sessions to PHP, rather than to Cake. PHP allows you to override a number of session-handler functions, essentially overriding the way sessions are stored in a method of your choosing. That could be storing sessions in a separate database, over a custom secure channel, or whatever crazy method you can come up with.

If you need to change the way session handling is done in PHP, there is a single function, session_set_save_handler, that controls the session-callback function. Passing this function the names of function that open, close, read, and write to the session is demonstrated below. An in-depth discussion of the session_set_save_handler function is outside the scope of this article (see Resources).


Listing 10. Redefining how PHP stores sessions
                    
function open($save_path, $session_name)
{
  global $sess_save_path;
 
  $sess_save_path = $save_path;
  return(true);
}

function read($id)
{
  global $sess_save_path;
 
  $sess_file = "$sess_save_path/sess_$id";
  return (string) @file_get_contents($sess_file);
}

...

session_set_save_handler("open", "close", "read", "write", "destroy", "gc");

The session-handling functions are redefined by the PHP functions: session_start(). Using this method has some advantages.

Advantages:

  • It's flexible. Any storage method supported by PHP.
  • If you don't override the session-handling functions, sessions will be stored the same way as all the other applications on your server.

Disadvantage:

  • Since PHP is set up to store sessions in the tmp directory by default, you could face some of the same disadvantages described above in "Storing sessions: 'cake'."

Deciding what method to use for handling session storage isn't always cut and dry. Most of the time, letting PHP handle your sessions will be fine. But ultimately, you will need to make that decision based on the particulars of your application.

In the next section, we discuss the Request Handler component and how you can use it to add Ajax functionality to your application.



Back to top



Go to the previous pagePage 3 of 9 Go to the next page