Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CodeIgniter: checking if user logged in for multiple pages

Tags:

codeigniter

I have a controller, which maps to section of my site and all of the pages within it (methods) should only appear if the user is logged in. Otherwise they should be redirected back to a login screen.

To get it working I've just done this:

function index() {

    if ($this->session->userdata('logged_in')) {
        $this->load->view('main');

    } else {
        redirect('/login');
    }
}

function archive() {

    if ($this->session->userdata('logged_in')) {

and so on... repeating that check in each method. What's the simplest way of doing this check once for multiple-or-all methods in the controller?

like image 361
gio Avatar asked May 07 '11 09:05

gio


3 Answers

You can run code in every method of a Controller by running it in the __construct() method:

function __construct()
{
    parent::__construct();
    if ( ! $this->session->userdata('logged_in'))
    { 
        // Allow some methods?
        $allowed = array(
            'some_method_in_this_controller',
            'other_method_in_this_controller',
        );
        if ( ! in_array($this->router->fetch_method(), $allowed)
        {
            redirect('login');
        }
    }
}

You can remove the "allowed" bits if you want to restrict access to the whole thing, but there are better ways to do this, like creating a base controller:

// Create file application/core/MY_Controller.php
class Auth_Controller extends CI_Controller {

    function __construct()
    {
        parent::__construct();
        if ( ! $this->session->userdata('logged_in'))
        { 
            redirect('login');
        }
    }
}

Then have your restricted controllers extend Auth_Controller instead of CI_Controller. Now your code will be run every time the controller is loaded.

More info on extending core classes: http://www.codeigniter.com/user_guide/general/core_classes.html#extending-core-class

Also of interest: http://php.net/manual/en/language.oop5.decon.php

like image 120
Wesley Murch Avatar answered Nov 10 '22 07:11

Wesley Murch


For codeIgniter 3 I modified Wesley Murch's answer to this

// Create file application/core/MY_Controller.php

<?php 
defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Controller extends CI_Controller {

function __construct()
{
    parent::__construct();
    $CI = & get_instance();
    $CI->load->library('session');
    $CI->load->helper('url');
    if ( !$this->session->userdata('logged_in'))
    { 
        redirect('login');
    }
}

}

Then in any controller to check authorization I used

class News extends MY_Controller { //code here }

If you use modules and different sessions for website users and admin users, you can use this code to perfectly redirect them to different login pages-

function __construct() {
    parent::__construct();
    $CI = & get_instance();
    $CI->load->library('session');
    $CI->load->helper('url');
   // echo "<pre>";print_r($this->router);echo "</pre>";

    /**
     * if webmaster then check admin session else check user session
     * But there may be some classes's method that doesn't requires login hence it is also need to check if
     * current request is for those methods before checking session
     */
    //to use $this->config->item('webmaster_name') this you have to define 
    // $config['webmaster_name'] = "webmaster"; in config.php file

    if ($this->router->module == $this->config->item('webmaster_name')) {
        if (!$this->session->userdata('admin')['id']) {
            redirect($this->config->item('webmaster_name').'/login');
        }
    } else {
        if (!$this->session->userdata('user')['id']) {
            redirect('login');
        }
    }
}

If you also want users to allow to access some methods from any particular controller without being logged in you can use this code -

function __construct() {
    parent::__construct();
    $CI = & get_instance();
    $CI->load->library('session');
    $CI->load->helper('url');

    //echo "<pre>"; print_r($this->router);echo "</pre>"; //_pr($this->config->item('excluded_auth'));
    /**
     * if webmaster then check admin session else check user session
     * But there may be some classes's method that doesn't requires login hence it is also need to check if
     * current request is for those methods before checking session
     */
    if ($this->router->module == $this->config->item('webmaster_name')) {
        if (!$this->session->userdata('admin')['id']) {
            redirect($this->config->item('webmaster_name') . '/login');
        }
    } else {
        if (array_key_exists($this->router->class, $this->config->item('exclude_auth')) && in_array($this->router->method, $this->config->item('exclude_auth')[$this->router->class])) {
            //echo "escape this method. don not validate for a session";
        } else {
            if (!$this->session->userdata('user')['id']) {
                redirect('login');
            }
        }
    }
}

Note: You can define a custom config file for defining your excluded methods like as-

//save file in application/config/without_auth_methods.php

<?php
     defined('BASEPATH') OR exit('No direct script access allowed');
     $config['exclude_auth']['news']       = array('index', 'view');
     $config['exclude_auth']['users']      = array('index');
like image 22
RN Kushwaha Avatar answered Nov 10 '22 07:11

RN Kushwaha


I use this function:

Then just call $this->isAuthorized from your controllers __construct.

It allows me to control what controllers are accessed and what methods are accessed too.

protected function isAuthorized()
{

    switch ( strtolower( $this->router->class ) )
    {
        case 'pages':
            $disallowLoggedOut = array( 'dashboard' );
            $disallowLoggedIn = array( 'index' );
        break;

        case 'users':
            $disallowLoggedOut = array( 'logout' );
            $disallowLoggedIn = array( 'register', 'login' );
        break;
    }

    if ( $this->session->userdata( 'loggedIn' ) ) 
    {       
        if ( in_array( $this->router->method, $disallowLoggedIn ) )
        {
            redirect( 'pages/dashboard' );
        }
    }
    else
    {       
        if ( in_array( $this->router->method, $disallowLoggedOut ) )
        {
            redirect( 'pages/index' );
        }
    }
}
like image 1
robingchan Avatar answered Nov 10 '22 06:11

robingchan