1

I'm trying to make a simple routing rule to allow only authenticated users to certain controllers.

To achieve this, I would like to run precontroller hook and check if the user is logged in using ci session. However, I have to know which controller the user wants to access. How do I know this in a hook function?

jjj
  • 235
  • 2
  • 16

5 Answers5

4

$this->router->fetch_class();

Extend CI_Controller and this should work.

jjj
  • 235
  • 2
  • 16
3

I dont think that hooks are best practice for what you want to achieve here

you may try the following: You need to create middle controller that you will extend instead of CI_Controller that will have authentication check and redirect the user to right controller

read this tutorial created by jondavidjohn step by step

http://jondavidjohn.com/blog/2011/01/scalable-login-system-for-codeigniter-ion_auth

You shoud be able to get the idea after 10 mins

Ahmed Gaber
  • 707
  • 1
  • 10
  • 27
  • 1
    why would it be considered a bad practice? Depending on the situation, if a controller has many methods with different authentication levels, controlling it at a router-level would yield a much cleaner code. – jjj Dec 21 '12 at 08:36
0

Cant you just put the authentication on the controller constructor ? It will be called when item instantiate and you can do the check there. Also you can always extend the CI_Controller and put the logic in there so that you can do your check in there (and use this->router->fetch_class() as suggested).

tix3
  • 1,142
  • 8
  • 17
  • 1
    that would make your codes very repetitive (DRY). it would be much better to just extend an additional class that extends the ci_controller if i really want to do it that way. – jjj Dec 21 '12 at 08:50
  • Yeap, you can just create a new class Secure_controller which extends the CI_Controller and add the check in that constructor. Then have all the controllers that you want checked extend that controller. – tix3 Dec 21 '12 at 08:55
  • (reply to your edited answer, not your second reply) yes that was what i was thinking. in the controller, have an array that contains the relationship of controller&method and auth level. that would yield a very clean code with a single place to manage the entire auth process. of course, unless the site gets huge – jjj Dec 21 '12 at 08:55
0

If you don't want to go the extended controller route, and I can see your logic there, then you have to use native PHP here because the CI object doesn't exist in the pre_controller_hook.

So, get the URI, then parse it to find the controller:

$uri = $_SERVER['REQUEST_URI'];
$segments = explode("/", $uri);

// if you're removing index.php from your urls, then
$controller = $segments[0];

// if you're not removing index.php
$controller = $segments[1];
swatkins
  • 13,530
  • 4
  • 46
  • 78
0

Extend CI_Controller in your autoload library Class.

Something like this:

class MyAuthLibrary extends CI_Controller {
    var $ci;

    function __construct() {

        $this->ci = &get_instance();
        $route = $this->ci->router->fetch_class();

        if( ($route !== 'login') && !$this->ci->session->userdata('email_address') ) {
            redirect('login');
        } 
    }

}
Slipstream
  • 13,455
  • 3
  • 59
  • 45