发一个防止重复提交的 token验证
本帖最后由 deader 于 2012-6-15 08:41 编辑这个是大概一年前写的了,很久没再敲代码,自己都有些看不懂了。希望对大家有帮助。
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');
.....
}
.........
/**
* 停止执行程序,给出错误信息,并写入错误日志。
* 所有参数由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>");
}
/**
* 获取表单的值
* @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);
}
}
........
/**
* 令牌验证
*/
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);
}
}
Controller 中使用如下:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Contents extends MY_Controller {
function __construct()
{
parent::__construct();
......
}
public function index()
{
$this->users_list();
}
/*添加文章*/
function content_add()
{
if($this->input->post('submit'))
{
//令牌验证,是否非法提交表单
parent::token_check(parent::obtain(parent::INPUT_TOKEN_NAME,'post',true));
if($this->form_validation->run() == true)
{
$post_data = parent::obtain('content');
$post_data['add_time'] = date('Y-m-d H:i:s');
$post_data['add_person'] = $this->session->userdata('username');
if($this->m_contents->add_content($post_data))
{
session_start();
$sessionid = $_SESSION['session_id'];
$this->m_contents->del_tmp_img_upload($sessionid);
redirect(s_url("/admin/contents/contents_list"));
}
else
{
parent::stop_doing(error_code('d'),error_level('ce'),error_message('d_add'));
}
}
else
{
parent::stop_doing(error_code('d'),error_level('e'),error_message('d_check'));
}
}
else
{
$data['input_token'] = parent::gen_input();
$data['editor'] = parent::editor("content");
$data['allcates'] = $this->cates->fetch_view_data();
$this->load->view('admin/contents/content_add',$data);
}
}
........
}
view中使用 如下:
<?php session_start();?>
<html xmlns="http://www.w3.org/1999/xhtml" class="off">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<title></title>
<link href="<?php echo admin_path().'/'?>statics/css/base.css" rel="stylesheet" type="text/css" />
<script language="javascript" type="text/javascript" src="<?php echo admin_path().'/'?>statics/js/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="<?php echo admin_path().'/'?>statics/js/jquery.validate.js"></script>
</head>
<body leftmargin="8" topmargin="8" >
<form action="/admin/contents/content_add" method="post" id="contentform" >
..............
<?php echo $input_token;?>
...........
</form>
</body>
</html>
怎么给代码字体变色呢,怎么变成“ [color=#ff0000]parent::token_check(parent::obtain(parent::INPUT_TOKEN_NAME,'post',true));”这种了 围观下 代码变色没有作用吧?为什么要变色,给自己看吗? 变色的地方 当然是最需要注意的了 :lol
页:
[1]