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.

January 29, 2011

Questions? Comments? Your 2¢'s? → @davidwinter