使用身份验证保护CodeIgniter 2应用程序的正确方法是什么?

时间:2012-11-29 22:59:21

标签: php codeigniter authentication codeigniter-2 ion-auth

我已正确安装Ion Auth并在我的服务器上运行。我也有默认的 CodeIgniter 2 “新闻”教程,在同一个CI安装中工作。我只是在玩耍,并对使用身份验证系统“封闭”或保护整个应用程序的正确方法感到好奇。

对于这个问题,让我们使用CI附带的“新闻”教程。

在我的index()控制器中的news.php函数内,我添加了条件代码以检查用户是否已登录。如果没有,则用户刚刚进入登录屏幕。

public function index() {
    $data['news'] = $this->news_model->get_news();
    $data['title'] = 'News archive';
    if ($this->ion_auth->logged_in()) {
        $this->load->view('templates/header', $data);
        $this->load->view('news/index', $data);
        $this->load->view('templates/footer');
    } else {
        redirect('auth/login', 'refresh');
    }
}

我可以看到这种方法有效,但直接的缺点是控制器中的每个功能也必须使用类似的条件逻辑进行修改,以保护所有其他页面视图。例如 - 检查登录,显示页面,否则转到登录页面......一遍又一遍。

这是应该做的吗?

如果某个应用程序已经构建并正在运行并且只是想要保护它,该怎么办?添加条件逻辑来检查控制器中每个页面视图的登录状态似乎不必要地冗长。

整个应用程序(所有视图)是否可以在一个地方受到保护,以最大限度地减少代码修改?如果是这样,怎么样?

3 个答案:

答案 0 :(得分:9)

为了保护整个控制器,您可以将身份验证检查作为eric.itzhak提到的__construct()电话。

为了保护整个应用程序,您可以扩展CI_Controller类,将auth放在该文件的构造函数中,然后最终通过MY_Controller而不是每个控制器中的CI_Controller进行扩展。

代码示例:

/* File: application/core/MY_Controller.php */
class MY_Controller extends CI_Controller
{
    function __construct()
    {
        parent::__construct();

        if ( ! $this->ion_auth->logged_in())
        {
            redirect('auth/login');
        }
    }
}

然后,在每个控制器中(注意MY_Controller,而不是CI_Controller):

class Controller_name extends MY_Controller
{
    function __construct()
    {
        parent::__construct();
    }

    // rest of controller methods
}

这些代码示例假设您正在自动加载(也可能)离子auth库。如果没有,请根据需要在MY_Controller文件中加载库。

这种方法有两个优点:

  1. 您只需要在要保护的每个控制器中将CI_Controller更改为MY_Controller。
  2. 如果您需要一个不受保护的控制器,即包含auth方法的控制器(如果您的auth控制器无法登录),则无需保护所有要求您登录:P - 将有一个重定向循环)。

答案 1 :(得分:2)

构造函数是要走的路。还有一些需要考虑的事情 - 如果你直接调用自己的方法而不是Ion Auth,它会变得更灵活。通常,登录过程的一部分是获取视图中显示的唯一值,或用于跟踪会话等的ID等。示例:在页面上显示用户名。

因此,将登录的离子身份验证推送到模型,添加获取用户信息或任何需要的方法。如果每个方法都不起作用,则返回false。然后在你的构造函数中检查它是否被返回

function __construct() {
    parent::__construct();
 // load the model
 $this->load->model( 'customer_model' );

 // if logged in, return $this->customer, available to all methods in class
 if(! $this->customer = $this->customer_model->verifyLogin() ) 
 { redirect('auth/login', 'refresh'); }
 } 

 public function index()
 {
   // pass customer to data 
  $data['customer'] = $this->customer ;

 // $customer->name will now be available in view


 } 

答案 2 :(得分:1)

我认为正确的逻辑是检查__construct方法中的用户状态,因为每次使用控制器时都会这样做。 不会保护整个ci应用程序,只保护此控制器中的方法,但我认为这样做会对你的情况有所帮助。

试试这个:

 public function __construct()
   {

        if (!$this->ion_auth->logged_in()) 
             redirect('auth/login', 'refresh');
   }