我有一个扩展到多个类文件的大项目。这个项目是为了赶在最后期限前完成的。这对项目的安全性造成了影响。简单地说,理论上任何人都可以在我的项目中调用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个用户类:"Admin"、"client"、"employee"。现在理论上,所有这些都可以调用这个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
。如果是,则应将其与当前登录用户的权限级别进行比较。如果不匹配,则函数应中断。如果根本没有定义,任何人都可以运行该函数。
有人对此有办法吗?我一片空白。
在调用任何函数之前,都需要调用一些函数。为此,请使用__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();
}