Authentication with CodeIgniter

Here’s how I do some basic authentication for a controller in CodeIgniter. It basically consists of creating a new class that extends the default Controller class. You then sub-class this on any controller that requires authentication.

Create your authentication controller in system/application/libraries and call it MY_Controller.php. It’s important that you prefix the controller name with MY_, or whatever you have specified $config['subclass_prefix'] as in your configuration.

<?php

class MY_Controller extends Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library('session');
        if (!$this->session->userdata('loggedin'))
        {
            header('Location: /sessions/login');
        }
    }
}

This basically checks if the session data for loggedin is set to true. If not, it’ll redirect the user to the /sessions/login URL. This means we have to create a basic controller to handle the sessions.

<?php

class Sessions extends Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library('session');
    }

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

    public function authenticate()
    {
        $this->load->model('user', '', true);
        if ($this->user->authenticate($this->input->post('username'), $this->input->post('password')))
        {
            $this->session->set_userdata('loggedin', true);
            header('Location: /');
        }
        else
        {
            header('Location: /sessions/login');
        }
    }

    public function logout()
    {
        $this->session->unset_userdata('loggedin');
        header('Location: /');
    }
}

The login view is a basic form with fields for username and password that submits to /sessions/authenticate. This controller then loads the user model and checks that a user with the username and password exists. If so, it sets the session data for loggedin to true and redirects the user back to the default controller. If not, it takes the user back to the login page.

Then to implement the authentication in a controller, simply do:

<?php

class SecretPlace extends MY_Controller
{
...

It’s a good idea to store your session data in your database and encrypt your cookies with $config['sess_encrypt_cookie'] = TRUE; in config.php. That way people won’t be able to snoop around and try to trick your application into thinking they’re authenticated.

2009-02-21 [, , ]

Comments

  1. Nice tutorial. Thanks.

    marco (2009-02-23 @ 03:14)
  2. Nice. Simple and easy to follow.

    Good tutorial.

    Wez (2009-02-23 @ 08:13)
  3. Great tutorial, Winter! I like your style to work with the extending features! I never was thinked about to work like that.

    Thanks!

    Joel Wallis (2009-02-23 @ 17:37)
  4. Excellent! I was looking for something as simple as this, as I found most of the recommended authentication libraries a little too featured for my requirement! Thanks!

    Aalaap Ghag (2009-05-14 @ 04:23)
  5. Good stuff, thanks.

    For anyone looking for the authenticate function for your users model, here’s a basic one. Of course you should probably be encrypting passwords with something like sha256.

    function authenticate($email, $password) { $this->db->where(‘email’, $email); $this->db->where(‘password’, $password); $query = $this->db->get(‘users’);

        if ($query->num_rows() > 0) :
            return TRUE;
        else:
            return FALSE;       
        endif;
    }
    
    k00k (2009-05-30 @ 15:01)
  6. Do you need to autoload the library? The only way I can get it to work is when I do. But then it seems all of my pages are protected by authenication (even my login page, which gives me an infinite loop).

    This is my autoload.php: $autoload['libraries'] = array(‘database’, ‘MY_Controller’);

    When I don’t have the autoload my default app comes up right away, even with this: class Application extends MY_Controller{

    Thanks!

    andy (2009-07-30 @ 16:55)
  7. I think this code does not follow the usual CodeIgniter form validation standards. I reckon you should have used a custom callback function or other built-in validation methods. Anyway, your codes seems longer but I think it works so congratulations on that!

    Jhourlad Estrella (2009-08-15 @ 13:55)
  8. @andy: I had the same issue. If your PHP code is written in “PHP4 style”, i.e. like this:

    class MyPage extends MYController { function MyPage() { parent::MYController(); } }

    then you need to be VERY careful to call parent::MY_Controller(), and not parent::Controller().

    A safer way to do this (though PHP5-specific) is:

    class MyPage extends MY_Controller { function construct() { parent::construct(); } }

    This works for me.

    Phil Pemberton (2009-09-05 @ 21:46)
  9. Hmm. Seems this site has Markdown enabled for comments…

    That’s supposed to be “MY-underscore-Controller”, not “MYController”.

    Phil Pemberton (2009-09-05 @ 21:47)
  10. Also, FYI, the boldfaced text is supposed to be “underscore-underscore-construct()”, then the same after “parent::”. This is in the PHP manual and most good PHP books, and should be listed under either “classes” or “object oriented programming”.

    Phil Pemberton (2009-09-05 @ 21:48)
  11. Don’t forget to actually call the extended constructor from your secretplace constructor. with:

    parent::MY_Controller();

    and not:

    parent::Controller();

    Good tutorial.

    Robbie (2009-10-21 @ 10:28)
  12. Dear all,

    As I am a newbie with CI, I found this tutorial very interesting. I however got some difficulties while implementing it. I think I created the right model but what I am stuck with is the header(Location: /path). How can I configure the default Location? I changed the base_url in the config.php but it doesn’t work.

    Thanks

    Jalal (2009-11-11 @ 15:47)
  13. Nice. Very helpful for me.

    Sangwon Park (2010-05-17 @ 13:17)
  14. This works for me. thnxz a lot, is there any library with users access rights?

    hanaptayo (2010-05-20 @ 15:32)
  15. Hi, I’m stuck with that error: Undefined property: MY_Controller::$session

    sessions and MyController are autoloaded. Here is MYController class:

    
    <?php

    class Welcome extends MY_Controller {

    function  __construct()
    {
        parent:: __construct();
    }
    
    function index()
    {
        $this->load->helper('url');
        $this->load->view('welcome_message');
    }
    

    }

    any ideas?

    Thanks

    Hairy One (2010-07-01 @ 06:18)
  16. Sorry, here is my MY_Controller class:

    
    <?php

    class MY_Controller extends Controller { public function construct() { parent::construct(); $this->load->library('session'); if (!$this->session->userdata('loggedin')) { header('Location: /sessions/login'); } } }

    Hairy One (2010-07-01 @ 06:21)

Powered by WP Hashcash