保护/限制用户组功能的良好做法

时间:2014-10-10 06:50:54

标签: php

我有一个扩展多个类文件的大项目。这个项目匆忙完成了截止日期。这对项目安全造成了影响。所以说实话,理论上任何人都可以 在我的项目中调用AJAX脚本并让它运行,因为脚本中的函数不是用户权限。当然,我会检查所有AJAX PHP脚本,以查看用户是否已登录。

所以这是一个例子:

// Update user information. This script is called with jQuery AJAX:
<?php
include('../../../config/config.php');
require_once('classes/Autoloader.php');

$iris = new IRIS();

if( !$iris->UUID() ){
    die( "Unauthorized access! ");
}

$result = array('success'=>true);

$users = new users();

try {
    $res = $users->createUser();
    $result = array( 'success' => true, 'result' => $_POST );
}
catch(Exception $e){
    $result = array( 'error' => true, 'errmsg' => $e->getMessage() );
}

echo json_encode( $result );

我有3个用户类:&#34;管理员&#34;,&#34;客户&#34;,&#34;员工&#34;。现在理论上,所有这些都可以调用这个PHP脚本,并修改用户,即使它只是管理员应该有权访问它。用户在数据库中指定了特权参数,我在项目中用常量定义:

define('USER_AUTH_LEVEL', $_SESSION['auth_level']);

我知道我可以更新每个AJAX PHP文件并设置:

if( USER_AUTH_LEVEL !== 1 ) { die( 'You do not have access' ); }

但我想做的是保护我的所有课程或部分课程。功能也是如此。让我们说:

class IRIS {
    public function doSomething(){
         // $function_access not defined, accessable by all
    }
    public function doSomethingAdmin(){
        $function_access = 1;
         // Should be limited to admins
    }
    public function doSomethingClient(){
         $function_access = 2;
         // Should be limited to clients
    }
}

我想要实现的是每次运行一个函数时运行的脚本,无论它运行的是什么类。此脚本应检查是否设置了参数$function_access。如果是,则应与当前登录用户的权限级别进行比较。如果不匹配,则该函数应该中断。如果根本没有定义,任何人都可以运行该功能。

有没有人有办法解决这个问题?我在这里完全空白。

1 个答案:

答案 0 :(得分:1)

您需要在任何函数调用之前调用某个函数。为此,请使用__call方法:

class IRIS extends Access {
    /* other methods here */

    // list all methods to allow some access levels.
    public function accessControll() {
       return [
          parent::ADMIN => ['doSomethingAdmin', 'doSomethingElseAdmin'],
          parent::USER => ['doSomething', 'doSomethingElse'],
       ];
    }
}

abstract class Access {
    // access levels defines
    const ADMIN = 1, USER = 2;

    public function __call($method, $arguments) {
        $accessLevel = -1;

        // get access level of current method
        foreach ($this->accessControll() as $key => $group) {
            if (in_array($method, $group)) {
                $accessLevel = $key;
                break;
            }
        }

        if (USER_AUTH_LEVEL !== $accessLevel) {
            throw new Exception('You do not have access');
            // OR header('HTTP/1.0 401 not authorized');
        }
    }

    // abstract, so every class, that extends it must have this method.
    abstract public function accessControll();
}