【问题标题】:What is proper way to secure CodeIgniter 2 application with authentication?使用身份验证保护 CodeIgniter 2 应用程序的正确方法是什么?
【发布时间】:2012-11-18 03:35:21
【问题描述】:

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

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

在我的news.php 控制器的index() 函数中,我添加了条件代码来检查用户是否已登录。如果没有,用户将被带到登录屏幕。

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');
    }
}

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

这是应该的方式吗?

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

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

【问题讨论】:

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


    【解决方案1】:

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

    因此,将 ion auth 登录检查推送到模型,添加获取用户信息的方法或您需要的任何内容。如果每个方法不起作用,则返回 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】:

      要保护整个控制器,您可以将身份验证检查放入 __construct() 调用中,如 eric.itzhak 所述。

      要保护整个应用程序,您可以扩展 CI_Controller 类,将身份验证放在该文件的构造函数中,然后最后在每个控制器中通过 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
      }
      

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

      这种方法有两个优点:

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

      【讨论】:

      • 我真的很喜欢这个。我想知道除了语义之外是否有任何技术优势。
      • 除了(可能)大幅减少您必须复制到每个控制器的代码量(即,它是 DRY)之外,并没有太大的区别。我更喜欢这种方法只是因为它很干净。
      【解决方案3】:

      我认为正确的逻辑是检查__construct 方法中的用户状态,因为每次使用控制器时都会执行此操作。它不会保护整个 ci 应用程序,仅保护此控制器中的方法,但我认为这对您的情况有用。

      试试这个:

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

      【讨论】:

      • 你的意思是,“它不会保护整个 ci 应用程序”?不过,这会保护整个“新闻”教程,对吧?
      • 一个应用程序可以是很多控制器做很多事情,这只是保护你正在使用的控制器。在这种情况下,它将使整个新闻教程受到保护,是的,但是您应该在更多的教程中理解这个概念。您应该阅读 MVC 以了解 CI 的工作原理。
      • 回答时,假设我已阅读所有 CI 文档、大量 CI 教程并了解 MVC 概念。请不要通过将我引回一般性内容来避免回答具体问题。因为我在这一点上寻求更多细节,这就是我发布这个问题的原因——学习。如果你的解决方案只保护当前模型,有没有办法保护整个应用程序?
      • 我一无所知,但我认为将其添加到您的控制器中并没有太多工作,但是我认为您可以尝试创建一些自定义库来检查构造并自动加载它的登录。
      • 别误会,我真的很喜欢你的建议,而且它似乎有效,但你给我的印象是你似乎并不完全确定。
      猜你喜欢
      • 2019-04-23
      • 2020-09-27
      • 1970-01-01
      • 1970-01-01
      • 2018-09-11
      • 2019-10-26
      • 2021-04-18
      • 2021-08-10
      • 1970-01-01
      相关资源
      最近更新 更多