>  기사  >  백엔드 개발  >  PHP에서 간단한 ACL 구현

PHP에서 간단한 ACL 구현

高洛峰
高洛峰원래의
2016-11-30 14:04:041184검색

代码如下: 
-- ACL 테이블 
-- 表적结构 `aclresources` 
`aclresources`가 존재하는 경우 테이블 삭제; 
존재하지 않는 경우 테이블 생성 `aclresources` ( 
`rsid` varchar(64) NOT NULL , 
`access` int(4) NOT NULL 기본값 0, 
`desc` varchar(240) NOT NULL 기본값 '', 
`created_at` int(10) unsigned NOT NULL 기본값 1, 
`updated_at` int(10) unsigned NOT NULL 기본값 0, 
PRIMARY KEY(`rsid`) 
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
-- 表的结构 `aclroles` 
`aclroles`가 존재하는 경우 테이블 삭제; 
`aclroles`가 존재하지 않는 경우 테이블 생성( 
`id` int(10) unsigned NOT NULL auto_increment, 
`rolename` varchar(32) NOT NULL , 
`desc` varchar(240) NOT NULL 기본값 '', 
`created_at` int(10) unsigned NOT NULL 기본값 1, 
`updated_at` int(10) unsigned NOT NULL 기본값 0, 
PRIMARY KEY(`id`), 
고유 키 `역할 이름`(`역할 이름`) 
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
-- 表的结构 `ref_aclresources_aclroles` 
`ref_aclresources_aclroles`가 존재하는 경우 테이블 삭제; 
존재하지 않는 경우 테이블 생성 `ref_aclresources_aclroles` ( 
`rsid` varchar(64) NOT NULL , 
`role_id` int(10) unsigned NOT NULL , 
기본 키(`rsid`,` role_id`) 
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
-- 表的结构 `ref_users_aclroles` 
`ref_users_aclroles`가 존재하는 경우 테이블 삭제; 
존재하지 않는 경우 테이블 생성 `ref_users_aclroles` ( 
`user_id` int(10) unsigned NOT NULL auto_increment, 
`role_id` int(10) unsigned NOT NULL , 
기본 키(`user_id` ,`role_id`) 
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 
-- 表的结构 `users` 
`users`가 존재하는 경우 테이블 삭제; 
CREATE TABLE `users` ( 
`id` int(10) unsigned NOT NULL auto_increment, 
`email` varchar(128) NOT NULL, 
`password` varchar(64) NOT NULL,
`nickname` varchar(32) NOT NULL 기본값 '', 
`roles` varchar(240) NOT NULL 기본값 '', 
`created_at` int(10) unsigned NOT NULL 기본값 1,
`updated_at` int(10) unsigned NOT NULL 기본값 0, 
기본 키(`id`), 
UNIQUE KEY `user_email`(`email`) 
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

php 类 
 代码如下: 
/**
* 단순 ACL 권한 제어 기능
*
* 테이블 정의
*
* 1. 리소스 정의(rsid, access, desc, Create_at, update_at)
* 2. 역할 정의 (id, rolename, desc,created_at,update_at)
* 3. 리소스-역할 연결(rsid, role_id)
* 4. 사용자-역할 연결(user_id, role_id)
*
* 따라 다름 db.php에서 sqlobject.php
*
* @author vb2005xu.iteye.com
*/ 
class AclBase { 
// --- ACL 访问授权 

/**
* 누구도 접근할 수 없습니다
*/ 
const NOBODY = 0; 

/**
* 누구나 액세스하도록 허용
*/ 
const EVERYONE = 1; 

/**
* 역할이 있는 사용자에게 액세스 허용
*/ 
const HAS_ROLE = 2; 

/**
* 역할이 없는 사용자의 액세스 허용
*/ 
const NO_ROLE = 3; 
/**
* 리소스-역할 연관에 정의된 역할만 액세스할 수 있습니다.
*/ 
const ALLOCATE_ROLES = 4; 

// 특정 이름 지정
public $tbResources = 'aclresources'; 
공개 $tbRoles = 'aclroles'; 
공개 $tbRefResourcesRoles = 'ref_aclresources_aclroles'; 
공개 $tbRefUsersRoles = 'ref_users_aclroles'; 

/**
* 리소스 접근 권한 포맷 및 return
*
* @return int
*/ 
정적 함수 formatAccessValue($access){ 
static $arr = array(self::NOBODY,self::EVERYONE,self::HAS_ROLE,self ::NO_ROLE,자기::ALLOCATE_ROLES); 
return in_array($access,$arr) ? $access : 자기::NOBODY; 


/**
* 리소스 생성 및 리소스 레코드의 기본 키 반환
*
* @param string $rsid
* @param int $access
* @param string $desc
*
* @return int
*/ 
function createResource($rsid,$access,$desc){ 
if (empty($rsid)) return false; 

$resource = array( 
'rsid' => $rsid, 
'access' => self::formatAccessValue($access), 
'desc' => $desc, 
'created_at' => CURRENT_TIMESTAMP 
); 

return SingleTableCRUD::insert($this->tbResources,$resource); 


/** 
* 修改资源,返回成功状态 

* @param 배열 $resource 
* @return int 
*/ 
function updateResource(array $resource){ 
if (!isset($resource['rsid'])) return false; 

$resource['updated_at'] = CURRENT_TIMESTAMP; 

return SingleTableCRUD::update($this->tbResources,$resource,'rsid'); 


/**
* 리소스 삭제
*
* @param string $rsid
* @return int
*/ 
function deleteResource($rsid){ 
if (empty($rsid)) return false; 
return SingleTableCRUD::delete($this->tbResources,array('rsid'=>$rsid)); 


/**
* 역할 생성 및 역할 레코드의 기본 키 반환
*
* @param string $rolename
* @param string $desc
*
* @return int
*/ 
function createRole($rolename,$desc){ 
if (empty($rolename)) return false; 

$role = array(
'rolename' => $rolename, 
'desc' => $desc, 
'created_at' => CURRENT_TIMESTAMP 
); 

return SingleTableCRUD::insert($this->tbRoles,$role); 


/**
* 역할 수정 및 성공 상태 반환
*
* @param array $role
* @return int
*/ 
function updateRole(array $role){ 
if (!isset($role['id'])) return false; 

if (isset($role['rolename'])) unset($role['rolename']); 
$role['updated_at'] = CURRENT_TIMESTAMP; 

return SingleTableCRUD::update($this->tbRoles,$role,'id'); 


/**
* 역할 삭제
*
* @param int $role_id
* @return int
*/ 
function deleteRole($role_id){ 
if (empty($role_id)) return false; 
return SingleTableCRUD::delete($this->tbRoles,array('role_id'=>(int) $role_id)); 


/**
* 리소스에 대한 역할을 지정하고 삽입하기 전에 매번 테이블에서 관련 레코드를 모두 제거합니다.
*
* @param int $rsid
* @param 혼합 $roleIds
* @param boolean $setNull 역할 ID가 존재하지 않는 경우 연관 테이블에서 자원을 지울지 여부
*/ 
함수 할당RolesForResource($rsid,$roleIds,$setNull=false,$defaultAccess=-1){ 
if (비어 있음($ rsid)) false를 반환합니다. 

$roleIds = Normalize($roleIds,','); 
if (empty($roleIds)){ 
if ($setNull){ 
SingleTableCRUD::delete($this->tbRefResourcesRoles,array('rsid'=>$rsid)); 

if ($defaultAccess != -1){ 
$defaultAccess = self::formatAccessValue($defaultAccess); 
$this->updateResource(array('rsid'=>$rsid,'access'=>$defaultAccess)); 

true를 반환합니다. 

false를 반환합니다. 


SingleTableCRUD::delete($this->tbRefResourcesRoles,array('rsid'=>$rsid)); 

$roleIds = array_unique($roleIds); 

foreach($roleIds를 $role_id로){ 
SingleTableCRUD::insert($this->tbRefResourcesRoles,array('rsid'=>$rsid,'role_id'=>(int) $role_id)); 

true를 반환합니다. 


function cleanRolesForResource($rsid){ 
if (empty($rsid)) return false; 
return SingleTableCRUD::delete($this->tbRefResourcesRoles,array('rsid'=>$rsid)); 


function cleanResourcesForRole($role_id){ 
if (empty($role_id)) return false; 
return SingleTableCRUD::delete($this->tbRefResourcesRoles,array('role_id'=>(int) $role_id)); 


/**
* 역할에 리소스를 할당하고 매번 테이블에서 관련 레코드를 모두 제거한 다음 삽입합니다.
*
* @param int $role_id
* @param 혼합 $rsids
*
* @return 부울
*/ 
함수 할당ResourcesForRole($role_id,$rsids){ 
if (empty($role_id)) return false; 

$role_id = (int) $role_id; 
$rsids = 정규화($rsids,','); 
if (empty($rsids)){ 
false를 반환합니다. 


SingleTableCRUD::delete($this->tbRefResourcesRoles,array('role_id'=>$role_id)); 

$rsids = array_unique($rsids); 

foreach($rsid를 $rsid로){ 
SingleTableCRUD::insert($this->tbRefResourcesRoles,array('rsid'=>$rsid,'role_id'=>$role_id) ); 

true를 반환합니다. 


/** 
* 为用户指派角color,每次均先전체부移除表中相关记录再插入 

*여기서 사용자가 많을 경우 성능 문제가 있을 수 있습니다... 나중에 최적화 방법을 생각해 보겠습니다
*
* @param int $user_id
* @param mix $roleIds
*
* @return 부울
*/
function 할당RolesForUser($user_id,$roleIds){
if (empty($user_id)) return false

$user_id = (int ) $user_id ;
$roleIds = Normalize($roleIds,',');
if (empty($roleIds)){
return false

SingleTableCRUD: :delete( $this->tbRefUsersRoles,array('user_id'=>$user_id))

$roleIds = array_unique($roleIds)

foreach($roleIds는 $입니다. roleId){
SingleTableCRUD::insert($this->tbRefUsersRoles,array('user_id'=>$user_id,'role_id'=>$role_id))
}
return true;
}

/**
* 사용자 역할 정보 지우기
*
* @param int $user_id
*
* @return boolean
*/
function cleanRolesForUser($user_id){
if (empty($user_id)) return false
return SingleTableCRUD::delete; ($this ->tbRefUsersRoles,array('user_id'=>(int) $user_id))
}

/**
* 역할의 사용자 연결 지우기
*
* @param int $role_id
*
* @return boolean
*/
function cleanUsersForRole($role_id ){
if (empty($role_id)) return false
return SingleTableCRUD::delete($this->tbRefUsersRoles,array('role_id'=>(int) $role_id)); >}

}

구체적인 탐지 코드는 다음과 같습니다.
코드 복사 코드는 다음과 같습니다.
/**
* 리소스에 대한 ACL 확인 수행
*
* @param string $rsid 리소스 식별자
* @param array $user 특정 사용자, 지정되지 않은 경우 현재 사용자 확인
*
* @return 부울
*/
function aclVerity ($rsid, 배열 $user = null){

if (empty($rsid)) return false
if (!CoreApp::$defaultAcl) {
CoreApp::$defaultAcl = new AclFlat();
}

$rsRow = aclGetResource($rsid);

// 정의되지 않은 리소스에 대한 기본 액세스 정책
if (!$rsRow) return false;

CoreApp::writeLog($rsRow,'test')

$rsRow['access'] = AclBase::formatAccessValue($rsRow['access'])

// 누구나 액세스할 수 있도록 허용
if (AclBase::EVERYONE == $rsRow['access']) return true

// 누구도 액세스할 수 없습니다
if ( AclBase::NOBODY == $ rsRow['access']) return false

// 사용자 정보 가져오기
if (empty($user)) $user = isset($_SESSION['SI- SysUser']) ? $_SESSION ['SI-SysUser'] : null

// 사용자가 로그인되어 있지 않으면 접근 권한이 없는 것으로 간주됩니다.
if (empty($user )) false를 반환합니다.

$user[ 'roles'] = 비어 있음($user['roles']) ? null: Normalize($user['roles'],';');
$userHasRoles = !empty($user['roles'])

/**
* 역할이 없는 사용자의 액세스 허용
*/
if (AclBase::NO_ROLE == $rsRow['access'] ) return $userHasRoles ? false :

/**
* 역할이 있는 사용자에게 액세스 허용
*/
if (AclBase::HAS_ROLE == $rsRow['access']) return $userHasRoles ? true;

// --- 사용자 리소스에 대한 작업 수행<-> 역할 확인
if ($userHasRoles){
foreach ($user['roles'] as $role_id){
if ( aclGetRefResourcesRoles($rsid,$role_id) )
return true;
}
dump($user);
}
return false; 🎜>코드 복사 코드는 다음과 같습니다:
/**
* 리소스에 대한 ACL 확인 수행
*
* @param string $rsid 리소스 식별자
* @param array $user 특정 사용자, 지정되지 않은 경우 현재 사용자 확인
*
* @return 부울
*/
function aclVerity($rsid ,array $user = null){

if (empty($rsid) ) false를 반환합니다.
if (!CoreApp::$defaultAcl) {
CoreApp::$defaultAcl = new AclFlat()
}

$rsRow = aclGetResource($rsid);

// 정의되지 않은 리소스에 대한 기본 액세스 정책
if (!$rsRow) return false

CoreApp::writeLog($rsRow,'test')

/*
* 확인 단계는 다음과 같습니다.
*
* 1. 먼저 리소스 자체의 액세스 속성을 확인합니다.
* EVERYONE => true, NOBODY => false * 계속 아래의 다른 속성을 확인하세요
* 2. 세션(또는 사용자 세션에서 테이블에서 설정된 역할 ID 가져오기)
* 3. 사용자에게 역할이 있으면 HAS_ROLE => true, NO_ROLE => false
* 4. 리소스 액세스 == ALLOCATE_ROLES인 경우
* 1. 캐시(또는 $tbRefResourcesRoles)에서 리소스에 해당하는 역할 ID 세트를 얻습니다
* 2. 사용자가 소유한 역할 ID 세트와 리소스에 해당하는 역할 ID 세트의 교집합을 찾습니다
* 3. 교차점이 존재함 => 그렇지 않으면=> false

$rsRow['access'] = AclBase::formatAccessValue($rsRow['access']); >
// 누구나 액세스할 수 있음
if (AclBase::EVERYONE == $rsRow['access']) return true

// 누구도 액세스할 수 없음
if; (AclBase::NOBODY == $ rsRow['access']) return false

// 사용자 정보 가져오기
if (empty($user)) $user = isset($_SESSION['SI -SysUser']) ? $_SESSION ['SI-SysUser'] : null

// 사용자가 로그인되어 있지 않으면 접근 권한이 없는 것으로 간주됩니다.
if (empty($ user)) return false

$user[ 'roles'] = 비어 있음($user['roles']) ? null : Normalize($user['roles'],';'); >
$userHasRoles = !empty($user['roles'])

/**
* 역할이 없는 사용자의 액세스 허용
*/
if (AclBase::NO_ROLE == $rsRow['access' ]) $userHasRoles ? false : true;

/**
* 역할이 있는 사용자에게 액세스 허용
*/
if (AclBase::HAS_ROLE == $rsRow['access']) return $userHasRoles ? ;

// --- 사용자 리소스에 대한 작업 수행<-> 역할 확인
if ($userHasRoles){
foreach ($user['roles'] as $role_id)
if ( aclGetRefResourcesRoles($rsid,$role_id) )
return true;
}
dump($user);
}
return false; {
if(empty($actTable)) return false;

global $globalConf;
$rst = null
$cacheId = null; actTable){
case CoreApp::$defaultAcl->tbResources:
$cacheId = 'acl-resources';
$rst = SingleTableCRUD::findAll(CoreApp:: $defaultAcl->tbResources) ;
// 해시 테이블 구조로 변환
if ($rst){
$rst = array_to_hashmap($rst,'rsid')
}
break; ::$defaultAcl->tbRoles:
$cacheId = 'acl-roles';
$rst = SingleTableCRUD::findAll(CoreApp::$defaultAcl->tbRoles)
//변환 해시 테이블 구조
if ($rst){
$rst = array_to_hashmap($rst,'id')
}
break
case CoreApp::$defaultAcl->tbRefResourcesRoles :
$cacheId = 'acl-roles_has_resources';
$rst = SingleTableCRUD::findAll(CoreApp::$defaultAcl->tbRefResourcesRoles)
if ($ rst){
$_ = array();
foreach ($rst as $row) {
$ref_id = "{$row['rsid']}<-|->{$ row['role_id']}";
$_[$ref_id] = $row;
}
unset($rst)
$rst = $_
}
break; >
if ($cacheId)
writeCache($globalConf['runtime']['cacheDir'] ,$cacheId ,$rst ,true)

if ($return) return $rst ;
}
/**
* 역할 리소스 액세스 제어 목록 재생성
*
* @param string $actTable ACL 테이블 이름
* @param boolean $return 재생성된 목록 반환 여부
*
* @ 혼합 반환
*/
function aclGetACT($actTable){
if (empty($actTable)) return false; array();

$cacheId = null;

switch($actTable){
case CoreApp::$defaultAcl->tbResources:
$cacheId = 'acl- resources';
case CoreApp::$defaultAcl->tbRoles:
$cacheId = 'acl-roles'
case CoreApp::$defaultAcl-> ;tbRefResourcesRoles:
$cacheId = 'acl-roles_has_resources';
break;

}

if (!$cacheId) return null ; isset($rst[$cacheId])) return $rst[$cacheId];

global $globalConf;
// 900
$rst[$ 캐시Id] = getCache($globalConf[' Runtime']['cacheDir'],$cacheId,0);
if ( !$rst[$cacheId] ){
$rst[$cacheId] = aclRebuildACT( $actTable,true); }

return $rst[$cacheId]
}
/**
* 역할 리소스 액세스 제어 목록 데이터 가져오기
*
* @param string $actTable ACL 테이블 이름
*
* @return 혼합
*/
function aclGetResource($rsid){
static $rst
if (!$rst){
$rst = aclGetACT(CoreApp::$defaultAcl->tbResources); 
if (!$rst) $rst = 배열(); 

isset($rst[$rsid]) 반환 ? $rst[$rsid] : null; 

/**
* 역할 기록 가져오기
*
* @param int $role_id
*
* @return array
*/ 
함수 aclGetRole($role_id){ 
static $rst = null; 
if (!$rst){ 
$rst = aclGetACT(CoreApp::$defaultAcl->tbRoles); 
if (!$rst) $rst = 배열(); 

isset($rst[$role_id]) 반환 ? $rst[$role_id] : null; 

/**
* 사용자 역할 연관 레코드를 가져옵니다. 이 방법을 사용하면 이 역할에서 리소스를 호출할 수 있는지 확인할 수 있습니다.
*
* @param string $rsid
* @param int $role_id
*
* @return 배열
*/ 
함수 aclGetRefResourcesRoles($rsid,$role_id){ 
static $rst = null; 
if (!$rst){ 
$rst = aclGetACT(CoreApp::$defaultAcl->tbRefResourcesRoles); 
if (!$rst) $rst = 배열(); 

$ref_id = "{$rsid}<-|->{$role_id}"; 
CoreApp::writeLog(isset($rst[$ref_id])?$rst[$ref_id]:'nodata',$ref_id); 
return isset($rst[$ref_id]) ? $rst[$ref_id] : null; 


http://code.google.com/p/php-excel/downloads/list 迷你好用的 EXCEL xml 输流方案 

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.