Php 限制用户未经授权的访问

Php 限制用户未经授权的访问,php,codeigniter,Php,Codeigniter,我目前正在Codeigniter框架中开发一个应用程序。我的项目由具有不同操作的不同级别的用户组成 我创建了一个Default\u模型,它处理与数据库的所有交互。所有控制器都与此单一模型交互 每个用户在注册时都有一个由用户选择的名称(只有在获得管理员的配置文件批准后,他才能访问配置文件) 我的实现: 让user1注册为指定的Level1,他可以访问名为operation1 我目前正在做的是在控制器中编写一个函数,user1通过www.example.com/page/operation1访问操作

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

我创建了一个
Default\u模型
,它处理与数据库的所有交互。所有控制器都与此单一模型交互

每个用户在注册时都有一个由用户选择的名称(只有在获得管理员的配置文件批准后,他才能访问配置文件)

我的实现:

user1
注册为指定的
Level1
,他可以访问名为
operation1

我目前正在做的是在控制器中编写一个函数,
user1
通过
www.example.com/page/operation1
访问操作。在函数中,我检查用户的指定(
==“level1”
),如果他有权访问我从数据库检索到的函数(在控制器的构造函数中加载所需数据包括指定,
用户ID
在会话中设置)。如果指定(如果不是
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
            }
    }
}

这纯粹是理论,解释了我将如何处理您的问题

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

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

这纯粹是理论性的,解释了我将如何处理您的问题

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

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

当您检查用户处于级别1时,基本上您必须对每个方法进行限制,无论用户是否被允许。。在您的情况下,当您使用if检查条件时,如果if失败,则不写入条件。。如果用户看到错误消息或更好,则应在失败时执行else。您应该使用_构造函数并在其中设置限制,并在不同的模式中分隔每个级别的用户

当您检查用户处于级别1时,基本上您必须对每个方法设置限制,无论是否允许用户。。在您的情况下,当您使用if检查条件时,如果if失败,则不写入条件。。如果用户看到错误消息或更好,则应在失败时执行else。您应该使用_构造函数并在其中设置限制,并在不同的模式中分隔每个级别的用户。您可以使用钩子以这种简单的方式只写一次

步骤1:

在config.php中启用钩子

$config['enable_hooks']=TRUE

步骤2: 使用如下钩子的post\u controller\u构造函数:
Location/config/hooks.php

$hook['post_controller_constructor'] = array(
    'class' => 'Auth_module',
    'function' => 'index',
    'filename' => 'Auth_module.php',
    'filepath' => 'hooks',
    'params' => array()
);
上面的代码Auth_module.php位于application/hooks/Auth_module.php文件夹中,函数名是在被调用类的构造函数之后调用函数的索引

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

}

您可以利用钩子实现只写一次的简单方式

步骤1:

在config.php中启用钩子

$config['enable_hooks']=TRUE

步骤2: 使用如下钩子的post\u controller\u构造函数:
Location/config/hooks.php

$hook['post_controller_constructor'] = array(
    'class' => 'Auth_module',
    'function' => 'index',
    'filename' => 'Auth_module.php',
    'filepath' => 'hooks',
    'params' => array()
);
上面的代码Auth_module.php位于application/hooks/Auth_module.php文件夹中,函数名是在被调用类的构造函数之后调用函数的索引

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

}

Show relevant code Show relevant code我怀疑是否有人可以直接调用模型中的函数,因为没有限制。它处理数据库查询并返回结果。我怀疑是否有人可以直接调用模型中的函数,因为没有限制。它处理数据库查询并返回结果在模型中再次检查结果?在您的案例中,您只有一个模型,并且有许多方法适合您。让我们举一个例子,这里有一个索引和角色方法,您必须在每个方法上放置条件语句,以检查是否允许用户访问此方法。所以,如果你有100种方法,你就有100种方法,每种方法上都有100个if语句,用来检查是否允许用户使用,或者在模型中再次勾选?在你的例子中,你只有一种模型,并且根据你的情况有很多方法。让我们来举个例子