限制用户未经授权的访问

时间:2016-06-22 13:54:51

标签: php codeigniter

我目前正在 Codeigniter 框架中开发一个应用程序。我的项目由不同级别的用户组成,他们有不同的操作。

我创建了一个Default_model来处理与数据库的所有交互。所有控制器都与此单一模型进行交互。

每个用户都有一个用户在注册时选择的名称(他在获得管理员批准后才能访问个人资料)。

我的实施:

user1注册名称为Level1,他可以访问名为operation1

的操作

我目前正在做的是在控制器中编写一个函数,user1通过www.example.com/page/operation1访问操作。在函数中我检查用户的指定(==="level1")如果他有权访问我从数据库中检索的函数(在控制器的构造函数中加载所需的数据包括指定,userid是如果指定(如果不是level1)不正确,则会显示404

目前我没有在模型中进行指定检查。如果调用模型中的函数,则返回数据。我是否必须再次检查他是否在模型中获得授权?我的方案是否有更通用或易于实现的方法?

更新

控制器: page.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Page extends CI_Controller {

    public $id;

    public function __construct() {
        parent::__construct();

        //load libraries and model(Default_model) here

        $this->id = $this->getData(); //loading data from DB, returns FALSE if session empty

        if ($this->id) {
            //has data
        } else {
            $data = array(
                'error' => 'Login to continue. <a href="' . base_url() . '">CLICK HERE</a>'
            );
            $this->load->view('error_view', $data);
        }
    }
    public function operation1()
    {
            if($this->id->designation === 1)
            {
                 //call model method because he is LEVEL 1 user
            }
    }
}

3 个答案:

答案 0 :(得分:4)

你可以利用钩子轻松地只写一次

第1步:

启用config.php中的挂钩

$config['enable_hooks'] = TRUE;

第2步: 使用这样的钩子的post_controller_constructor:Location /config/hooks.php

$hook['post_controller_constructor'] = array(
    'class' => 'Auth_module',
    'function' => 'index',
    'filename' => 'Auth_module.php',
    'filepath' => 'hooks',
    'params' => array()
);

The code above,Auth_module.php is reside in the folder application/hooks/Auth_module.php and the function name is index that function is called after the constructor of called class

Auth_module.php代码,如

<?php


class Auth_module {

    var $CI;
    var $user_id;
    var $role_id;
    var $collegeId;

    public function __construct() {
        $this->CI = & get_instance();
        $this->CI->load->library('session'); //if it's not autoloaded in your CI setup
        $admin_user_data = $this->CI->session->userdata('admin_user_data');
        $this->CI->load->model('admin_model');
        $this->CI->load->library('user_agent');
    }

    public function index() {
           if (!empty($this->user_id)) {

            $class= $this->CI->router->fetch_class();          

            $method= $this->CI->router->fetch_method();
            $role_name = $this->getRoleName($this->role_id);




            if ($role_name) {
                $Adminpermission = $this->CI->admin_model->getPermissions($class,$role_name);
                $Adminpermission_lower = array();
                foreach($Adminpermission as $mm_name)
                    $Adminpermission_lower[]  = strtolower($mm_name);


                if(!empty($Adminpermission)){
                    if(in_array($method, $Adminpermission)  || in_array($method, $Adminpermission_lower)){
                            $log_data['access'] =   'success';
                            //* all is ok here*/
               }else  if($class !='dashboard' and $class !='admin'){

                         $message='You don\'t have permissions to access this module. Please contact your administrator.';
                         $this->redirectMethod($message,$class); 
                         $log_data['access'] =  'failed';
                    }

                }else if($class !='dashboard' and $class !='admin'){
                     $message='You don\'t have sufficient permissions.please contact your administrator.';
                     $this->redirectMethod($message); 
                     $log_data['access'] =  'not defined in db';
                }

            } 
            else if($class !='dashboard' and $class !='admin') {
                $message='Request role is not defined. Please contact to your administrator or mail : test@test.com .';
                $this->redirectMethod($message);
                $log_data['access'] =   'role name not defined';
               }

        }




    }

     public function redirectMethod($message,$class=''){
               $message =  "<div class='alert alert-danger' role='alert'>".$message."</div>" ;
                $this->CI->session->set_flashdata('flashMessage', $message);
               if($class==null){
                redirect('dashboard');
               }else{
                   redirect($class);
               }
     }

     public function getRoleName($id) {
         $master_db = $this->CI->load->database('master', TRUE); 
         $result = $master_db->query("select role_name from role where id='$id'");

        $num_rows = $result->num_rows();
        if ($num_rows == 1) {
            return $result->row()->role_name;
        } else {
            return false;
        }
    }

}

根据您的要求修改auth文件。

答案 1 :(得分:1)

这是纯粹的理论,并解释了我如何处理你的问题。

  • 创建一个默认控制器,让所有其他控制器扩展此
  • 在此基本控制器中设置public $accessLevel = 0;
  • 在每个控制器的顶部定义相同的访问级别
  • 可选:如果需要,在控制器的方法中覆盖此级别
  • 在呈现视图文件之前,请检查用户的accessLevel是否等于或高于所需的accessLevel

回答你的问题。您不必在模型中仔细检查这一点。这是应该在您的控制器中完成的逻辑。但是,您可以将所有页面存储在数据库中,并在那里为它们提供accessLevel。然后,您可以检查是否允许用户访问查询中的页面。

答案 2 :(得分:0)

当你检查用户是否处于1级基本上你必须对每个方法施加限制,而不允许用户..在你检查条件的情况下,如果你没有写条件,如果失败..否则应该执行当if失败时用户看到错误消息或更好你应该使用__constructor并在那里放置限制并在不同模态中分隔每个级别的用户