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.