Access Control Library for Codeigniter
先检讨。比较浮躁,先前帖的Codeigniter ACL library 有较大的bug。配置和使用方法也没有说太多。今天正好用到,调试了一下。重新发布。嗯,这个也是淡水在ci在官网论坛上挖到的。还有个autoacl的,也是基于这个修改的。不过淡水觉得太耦合了,而且繁琐了。还是没有采用。
先来library:
/**
* MX_ACL - Access Control Library PHP5
*
* Notes:
* $config['cache_path'] must be set
*
* Install this file as application/libraries/MX_ACL.php
*
* @copyright Copyright (c) Wiredesignz & Maxximus 2009-11-03
* @version 1.1
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
class MX_ACL
{
private $_config, $_cache_path;
public function __construct() {
$this->load->helper('url');
$this->load->library('session');
$this->load->config('mx_acl', TRUE);
$this->_config = $this->config->item('mx_acl');
#$this->_cache_path = $this->config->item('cache_path');
$this->_cache_path = $this->config->item('cache_path', 'mx_acl');
/* previous flashdata is available to views */
$this->load->vars($this->_config['error_var'], $this->session->flashdata($this->_config['error_var']));
/* run the access control check now */
($this->_config['check_uri']) AND $this->check_uri();
}
/**
* Check the current uri and user privileges against the cached ACL array
* Redirect if access is denied
*
* @return void
*/
public function check_uri() {
/* Load the cached access control list or show error */
(is_file($cached_acl = $this->_cache_path.'mx_acl'.EXT)) OR show_error($this->_config['error_msg']);
$acl = include $cached_acl;
/* Match current url to access list */
#if (is_array($acl) AND $acl = $this->match_uri($this->current_uri(), $acl)) {
if (is_array($acl) AND $acl = $this->match_uri(strtolower($this->current_uri()), $acl)) {
/* Check session group against access level group */
$allow_access = (bool)(in_array($this->session->userdata($this->_config['session_var']), $acl['allowed']));
/* Additional check to allow IP addresses in range */
if ($allow_access AND isset($acl['ipl']))
{
if (is_array($acl['ipl']))
{
$allow_access = $this->check_ip($acl['ipl']);
}
}
if ($allow_access == FALSE) {
/* Set a return url into the session */
$this->session->set_userdata('return_url', $this->uri->uri_string());
/* set the error message... */
$error_msg = (isset($acl['error_msg'])) ? $acl['error_msg'] : $this->_config['error_msg'];
/* set a flash message... */
$this->session->set_flashdata($this->_config['error_var'], $error_msg);
/* redirect to absolute url */
die(header("Location: ".$acl['error_uri'], TRUE, 302));
}
}
}
/**
* Return the access control profile for a given url
*
* @return string
* @param string $current_uri
* @param array $acl
*/
private function match_uri($current_uri, $acl) {
if (array_key_exists($current_uri, $acl)) {
return $acl[$current_uri];
} else {
if ($pos = strripos($current_uri, '/')) {
return $this->match_uri(substr($current_uri, 0, $pos), $acl);
}
}
}
/**
* Returns the current uri string from segments
*
* @return string
*/
private function current_uri() {
return implode('/', $this->uri->rsegments);
}
/**
* Checks the remote IP address against the specified $ipl array
*
* @return bool
* @param array $ipl
* @param string $remote_ip[optional]
*/
private function check_ip($ipl, $remote_ip = NULL) {
/* Convert ip address into a double (for lousy OSes)*/
$remote_ip = floatval(ip2long(($this->session->userdata('ip_address'))));
/* Loop through the ip list array */
foreach ($ipl as $allowed_ip) {
/* Replace '*' (for IP ranges) with a suitable range number */
$min = str_replace("*", "0", $allowed_ip);
$max = str_replace("*", "255", $allowed_ip);
/* Check for a match */
if (($remote_ip >= floatval(ip2long($min))) AND ($remote_ip <= floatval(ip2long($max)))) {
return TRUE;
}
}
}
public function __get($var) {
static $CI;
(is_object($CI)) OR $CI = get_instance();
return $CI->$var;
}
}
/* End of file MX_ACL.php */
/* Location: ./application/libraries/MX_ACL.php */
再来配置文件:
/**
* MX_Acl configuration
*
* Save this file as application/config/mx_acl.php
*/
$config = array(
'check_uri' => TRUE,
'error_var' => 'error',
'error_msg' => 'You don\'t have sufficient access rights to view this page!',
'session_var' => 'role_id',
'cache_path' => 'application/acl/',
);
具体的acl,没有写入到db,直接放到上面的cache_path中的:
/**
* This is the cached access control list
*
* save this file as {cache_path}/mx_acl.php
*/
return array(
'setting/update' => array( // the "module/controller/method" to protect
'allowed' => array(1), // the allowed user role_id array (eg.$this->session->set_userdata('role_id','1'))
'ipl' => array('127.0.0.1'), // the allowed IP range array or FALSE(allowed all ip)
'error_uri' => site_url('secure/setting'), // the url to redirect to on failure
'error_msg' => 'You do not have permission to update this page!',
),
'page/update' => array(
'allowed' => array(1, 2, 3),
'ipl' => array('127.0.0.0','127.0.0.*'),
'error_uri' => (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : site_url('secure/page'),
'error_msg' => 'You do not have permission to update this page!',
),
);
staticpage的内容,处理未授权显示:
class Staticpage extends Controller
{
function error_auth()
{
show_error($this->session->flashdata('error'),203);
}
}
登录时给出相应的角色:
基本就是这样了。role_id使用了ci自带的session;errror用的也是的session的flashdata。嗯,就是这样,没有了。