Photo of David Winter

david winter

Authentication with CodeIgniter 2.0

I’ve started using CodeIgniter again recently, and have noticed that my how-to on implementing basic authentication could do with an upgrade for version 2.0.

The process is identical. We subclass the base CI_Controller class. This simply checks whether a logged in session is present. If not, it redirects the user to a sessions controller that can handle the logging in of a user. Once the user is logged in, the controller acts as normal.

So, first up, lets create our basic subclass:

<?php

class MY_Controller extends CI_Controller
{
	function __construct()
	{
        parent::__construct();

        $this->load->library('session');

        if (!$this->session->userdata('loggedin'))
        {
            redirect('sessions/login');
        }
	}
}

Now, this needs to be saved to application/core. This is important. You can’t add it to application/library like with the previous how-to. There have been some changes to CI that require the change. This new class is also auto-loaded automatically.

Now, the sessions controller needs to extend CI_Controller. Users don’t need to be authenticated to access this controller.

<?php

class Sessions extends CI_Controller
{
	function __construct()
	{
        parent::__construct();

        $this->load->library('session');
	}

	function login()
	{
        $this->load->view('header');
        $this->load->view('login');
        $this->load->view('footer');
	}

	function authenticate()
	{
        $this->load->model('user', '', true);

        $user = $this->input->post('user');

        if ($this->user->authenticate($user['email'], $user['password']))
        {
            $this->session->set_userdata('loggedin', true);
        }

        redirect('/');
	}

	function logout()
	{
        $this->session->unset_userdata('loggedin');

        redirect('/');
	}
}

Your login view will look something like this:

<h2>Login</h2>
<?php echo form_open('sessions/authenticate'); ?>
	<dl>
        <dt><?php echo form_label('Email', 'user_email'); ?></dt>
        <dd><?php echo form_input(array(
            'name' => 'user[email]',
            'id' => 'user_email'
        )); ?></dd>

        <dt><?php echo form_label('Password', 'user_password'); ?></dt>
        <dd><?php echo form_password(array(
            'name' => 'user[password]',
            'id' => 'user_password'
        )); ?></dd>
	</dl>
	<ul>
        <li><?php echo form_submit('submit', 'Login'); ?></li>
        <li><a href="<?php echo site_url('/'); ?>">Cancel</a></li>
	</ul>
<?php echo form_close(); ?>

Here’s a basic user model you could use. It includes hashing with extra salt security:

<?php

class User extends CI_Model
{
	public function authenticate($email, $password)
	{
        // get salt

        $salt = $this->db->select('salt')->get_where('users', array('email' => $email))->row()->salt;

        if ($salt)
        {
            // hash password with salt and find user

            $hash = sha1($salt.sha1($salt.$password));

            $user = $this->db->select('id')->get_where('users', array(
                'email' => $email,
                'hash' => $hash
            ))->row();

            return $user;
        }

        return false;
	}
}

Now all that’s left is to change the parent classes of the controllers that we want protected from CI_Controller to MY_Controller.

<?php

class Admin extends MY_Controller
{
	...

Authentication is now in place.