CodeIgniter Forums
Redirect in constructor: good practice? - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forumdisplay.php?fid=23)
+--- Thread: Redirect in constructor: good practice? (/showthread.php?tid=2604)



Redirect in constructor: good practice? - El Forum - 08-14-2007

[eluser]codex[/eluser]
If a user is not logged I want to restrict access to specific parts of a website. Is this the way to do it? I mean put the redirect in the constructor.

Code:
function Home()
    {
        parent::Controller();
        
        if (!$this->session->userdata('uid')) {
            redirect('/test/');
        }    
    }



Redirect in constructor: good practice? - El Forum - 08-14-2007

[eluser]Phil Sturgeon[/eluser]
Two quick things to make this a bit ore friendly.

make a helper called logged_in() with the code:

Code:
function logged_in(){

$CI =& get_instance();
$CI->load->library('session');

return (!$CI->session->userdata('uid'));
}

This will return true or false from the function, and you can use this all over the place if you put it on autoload. Also means that you can at any point in the development change the session name, change to using custom made database login sessions, intergrate with Google API, whatever! Keep things modular wherever possible ^_^.


Also, yea constructor is one place to do this. You could take another approach like I often do and make a hook if you want your login checking to cover ALL pages. If you only want it to cover some, or want it to cover all BUT some, then you could make a config array with allowed pages like so:

Code:
/*
|--------------------------------------------------------------------------
| Allowed Pages
|--------------------------------------------------------------------------
|
| These pages will be ignored by the permisions checker. All other pages
| will force users to login
|
*/
$config['require_login'] = TRUE;

// Pages that will always be open to people
$config['allowed_pages'] = array(
    // Default, leave these here!!
    'account/login',
    'account/register'

    'photos/browse',
    'portal/index'
    );

Then have some code in the hook like:

Code:
$class = $CI->uri->router->class;
    $method = $CI->uri->router->method;    
    
    // if no-one is logged in
    if(!loggedIn() && !in_array($class.'/'.$method, $CI->config->item('allowed_pages'))):
           redirect('login');
        endif;

Thats if you want to make things complicated :p, its a good method tho!


Redirect in constructor: good practice? - El Forum - 08-14-2007

[eluser]codex[/eluser]
Hmm, that's a bit too complicated at the moment. But thanks!


Redirect in constructor: good practice? - El Forum - 08-14-2007

[eluser]Phil Sturgeon[/eluser]
Ok well ignore the stuff about hooks, but still do the thing with the helper. You wont believe how often you will change things like this. I have changed what defines users as logged in many times during development, this would be a good way to ensure it will always work.


Redirect in constructor: good practice? - El Forum - 08-14-2007

[eluser]Iksander[/eluser]
I like your idea using hooks, pyro.


Redirect in constructor: good practice? - El Forum - 08-14-2007

[eluser]smith[/eluser]
I like to end script after redirect.
didn't test it with CI, but in old fashioned php scripts header is just one line of text telling browser to go to other page. so, if you have some code after that it will be executed and maybe print more data, beside header redirect part. calling your script from command line, simulating http request, would show that extra printed chars, together with header redirect part. my english is not so good, so i am sorry if i am using too much words to explain something simple Smile

so, my addition to this conversation would be:
Code:
redirect('login');
    exit();



Redirect in constructor: good practice? - El Forum - 08-14-2007

[eluser]Rick Jolly[/eluser]
codex, if you are still interested I think what you are doing if fine. I often take it a step further and do the redirect in the constructors of parent controllers. For example, for all admin back-end pages I extend an "admin" parent controller. That way I only need to do the check and redirect in the parent.


Redirect in constructor: good practice? - El Forum - 08-15-2007

[eluser]Cybolic[/eluser]
Rick Jolly, that sounds pretty interesting.
I'm not really into using redirects at all, so the idea of having a parent controller sounds really intriguing, could you elaborate on this?


Redirect in constructor: good practice? - El Forum - 08-15-2007

[eluser]codex[/eluser]
[quote author="Cybolic" date="1187206189"]Rick Jolly, that sounds pretty interesting.
I'm not really into using redirects at all, so the idea of having a parent controller sounds really intriguing, could you elaborate on this?[/quote]

Rick, please do!!


Redirect in constructor: good practice? - El Forum - 08-15-2007

[eluser]Rick Jolly[/eluser]
My pleasure.
Code:
class AdminController extends Controller
{
   function AdminController()
   {
      parent::Controller();

      $this->load->helper('url');
      if (!$this->session->userdata('uid'))
      {
         redirect('/login');
         exit();
      }
   }
}
and assuming the parent admin controller is a file called admin_controller.php in your controllers directory:
Code:
include(APPPATH . '/controllers/admin_controller.php');

// This controller is only be accessible by logged-in admin users since it extends the AdminController
class SomeProtectedController extends AdminController
{
   function SomeProtectedController()
   {
      parent::AdminController();
   }
}

I take inheritance to the extreme. Usually, I'll have a site-wide parent controller. I can do referer checks, cookie checks, etc. in there. The admin parent controller could actually extend the site-wide parent controller. Usually, any group of related controllers will extend one common parent.

I prefer not to use hooks because they aren't linked to the rest of the code. When using hooks for a login check, how would anyone know where login checks are being done by looking at the code?