|
发表于 2012-6-14 16:18:29
|
显示全部楼层
很久没敲代码了,现在分享一个我以前写的 MY_Controller,含有令牌验证(防止重复提交的)
PHP复制代码 <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
//基础控制器
class MY_Controller extends CI_Controller
{
function __construct ()
{
parent ::__construct ();
$this->load->library('form_validation');
$this->load->library('encrypt');
$this->load->model('admin/m_resources','m_resources');
$this->load->model('admin/m_rights','m_rights');
$this->load->model('admin/m_groups','m_groups');
$this->_init (); //自动检查用户是否登录及权限判断
}
function _init ()
{
//任何未登录的用户都初始化为guest组
if( ! $this->session->userdata('groups'))
{
$this->session->set_userdata(array('groups'=>'guest'));
}
$this->_check_url_permisson ();
}
/**
* 检查url权限,如果可以访问则正常进行,若无权限则提示并终止执行
* 后续扩展字段权限
* 注意:需要严格定义资源
*/
function _check_url_permisson ()
{
$current_url = $this->uri->uri_string() ? trim('/'.$this->uri->uri_string()) : '/welcome';
@$resource_id = $this->m_resources->get_resources_by_url('id',$current_url)->result();
$current_resource_id = $resource_id ? $resource_id[0]->id : 0;
//如果当前角色为guest,则直接获取guest权限,不必登录
if($this->session->userdata('groups') && $this->session->userdata('groups') == 'guest')
{
$res = $this->m_groups->get_group_by_name('guest')->result();
$gid = $res[0]->id;
@$guest_resource = $this->m_rights->get_resources_by_gid('resource_id',$gid)->result(); //guest组所拥有的权限
if($guest_resource && is_array($guest_resource))
{
foreach ($guest_resource as $grs)
{
$rest[] = $grs->resource_id;
}
}
@$current_gp_res = @$rest; //guest组所拥有的权限
$this->session->set_userdata('resources',$current_gp_res);
}
$my_resources = $this->session->userdata('resources');
if($my_resources && is_array($my_resources) && @in_array($current_resource_id,$my_resources))
{
return ;
}
else
{
$this->_check_login ();
}
}
/**
* 检查是否登录
*
*/
function _check_login ()
{
if($this->session->userdata('is_login') && $this->session->userdata('is_login') === true)
{
return ;
}
else
{
redirect (s_url ('/admin/auth/login'),'location');
}
}
/**
* 生成在线编辑器
*
* @param string $area 编辑器输入域名称
* @param string $value 编辑器输入域值
* @param number $width 宽度
* @param unknown_type $height 高度
* @param unknown_type $autoSave 是否自动保存
* @return 编辑器域
*/
public function editor ($area,$value='',$width=630,$height=400,$autoSave=false)
{
//加载在线编缉器
$this->load->library('seditor');
$editor = $this->seditor->SunEditor($area);
$editor->Value = $value;
$editor->BasePath = 'editor';
$editor->Height= $height;
$editor->Width = $width;
$editor->AutoSave = $autoSave;
return $editor->Create();
}
/**
* 获取表单的值
* @param $name 表单元素名称
* @param $type 提交方式,默认为post
* @param $xxsf 让取得的数据经过跨站脚本过滤(XSS Filtering),默认为false,开启为true
*/
public function obtain ($name,$type='post',$xxsf=false)
{
if($type == 'post')
{
return $this->input->post($name,$xxsf);
}
else if($type == 'get')
{
return $this->input->get($name,$xxsf);
}
else
{
return $this->input->get_post($name,$xxsf);
}
}
/*pagination 分页程序
* $where: 需要分页的url地址,即完整的分页控制器/方法
* $total_rows: 需要分页的数据总行数,通过查询数据库取得
* $per_page: 每页中希望显示信息的数量
* $uri_segment: URI的哪个部分包含页数
* $num_links: 显示分页提示数量
* $first_url: 分页链接首页链接
*/
function _pagination ($array)
{
$this->load->library('spagination');
$config['pagination_fix'] = true; // 是否启用分页修正功能,如设置为 false 则和系统自带分页类无异
$config['base_url'] = $array['where'];
$config['total_rows'] = $array['total_rows'];
$config['per_page'] = $array['per_page'];
$config['uri_segment'] = $array['uri_segment'];
$config['num_links'] = $array['num_links'];
//$config['first_url'] = $array['first_url']; // 分页链接首页链接
//以下为默认设置,可以自行修改
$config['full_tag_open'] = '<div class="pagination">'; //可根据需要改为<p>
$config['full_tag_close'] = '</div>'; //可根据需要改为</p>
$config['first_link'] = '首页';
$config['last_link'] = '末页';
$config['next_link'] = '下一页 >';
$config['prev_link']= '< 上一页';
$config['cur_tag_open'] = '<a class="current">';
$config['cur_tag_close'] = '</a>';
//修正样式开始
$config['cur_rows_tag_open'] = '<a class="number">当前第 ';
$config['cur_rows_tag_middle'] = ' ~ ';
$config['cur_rows_tag_close'] = ' 条</a>';
$config['total_rows_tag_open'] = ' <a class="number">共 ';
$config['total_rows_tag_close'] = ' 条</a>';
$config['total_pages_tag_open'] = ' <a class="number">计 ';
$config['total_pages_tag_close'] = ' 页</a>';
//修正样式结束
/*以下配置默认关闭,可以通过css来美化分页效果,配置格式应为:
* $config['first_tag_open'] = "<div class='someclass'>";
* $config['first_tag_close'] = "</div>";
*/
//$config['first_tag_open'] = '<div>';
//$config['first_tag_close'] = '</div>';
//$config['last_tag_open'] = '<div>';
//$config['last_tag_close'] = '</div>';
//$config['num_tag_open'] = '<div>';
//$config['num_tag_close'] = '</div>';
//$config['prev_tag_open'] = '<div>';
//$config['prev_tag_close'] = '</div>';
//$config['next_tag_open'] = '<div>';
//$config['next_tag_close'] = '</div>';
$this->spagination->initialize($config);
}
/**
* 停止执行程序,给出错误信息,并写入错误日志。
* 所有参数由helper提供
*
* @param $error_code 错误代码,用于区分错误类别
* @param $error_level 错误级别
* @param $error_message 错误提示信息
*/
public function stop_doing ($error_code='',$error_level='',$error_message='')
{
$this->load->library('slog');
//写入日志
$error_url = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$this->slog->process_logs($error_url,$error_code,$error_level,$error_message);
$rediret_url = 'http://'.$error_url;
header("Content-type:text/html; charset=utf-8");
die("<script type=\"text/javascript\">alert(\"错误信息!\\n \\n错误代码:".$error_code."\\n错误级别:".$error_level."\\n错误信息:".$error_message."\"); window.navigate(\"$rediret_url\");</script>");
}
/**
* 令牌验证
*/
const FORM_TOKEN_KEY = 'form_token_key';
const INPUT_TOKEN_NAME = 'input_token_name';
/**
* 生成令牌
*
* @return string
*/
public function gen_token ()
{
$hash = md5(uniqid(rand(), true));
$token = sha1($hash);
return $token;
}
/**
* 生成session令牌
*
*/
public function gen_session_token ()
{
//生成token
$token = $this->gen_token();
//删除session中原来的token
$this->destroy_stoken();
//将新的token注册到session
$this->session->set_userdata(self::FORM_TOKEN_KEY,$token);
}
/**
* 生成隐藏输入域表单
*
* @return 表单
*/
public function gen_input ()
{
$this->gen_session_token();
$token_input = "<input type=\"hidden\" name=\"".self::INPUT_TOKEN_NAME."\" value=\"".$this->session->userdata(self::FORM_TOKEN_KEY)."\" readonly=\"true\" /> ";
return $token_input;
}
/**
* 检测token是否合法,如果合法则继续执行,否则跳出
*
* @param string $token_input 页面提交的token
*/
public function token_check ($token_input)
{
// 检测session中是否已注册token
if($this->is_stoken())
{
if($token_input)
{
if($token_input == $this->session->userdata(self::FORM_TOKEN_KEY))
{
$this->destroy_stoken();
}
else
{
$this->destroy_stoken();
$this->stop_doing(error_code ('d'),error_level ('ce'),error_message ('d_add'));
}
}
else
{
$this->destroy_stoken();
$this->stop_doing(error_code ('v'),error_level ('ce'),error_message ('v_null'));
}
}
else
{
$this->destroy_stoken();
$this->stop_doing(error_code ('s'),error_level ('e'),error_message ('s_check'));
}
}
/**
* 销毁token
*
* @return bool
*/
public function destroy_stoken ()
{
$this->session->unset_userdata(self::FORM_TOKEN_KEY);
return true;
}
/**
* 检测token是否存在
*
* @return bool
*/
public function is_stoken ()
{
if($this->session->userdata(self::FORM_TOKEN_KEY))
return true;
else
return false;
}
/**
* 合并数组中的相同项
*/
function array_multi_unique ($ar)
{
$ar = array_map('serialize', $ar);
$ar = array_unique($ar);
return array_map('unserialize', $ar);
}
} 复制代码 |
评分
-
查看全部评分
|