这篇文章主要介绍了PHP -- ThinkPHP框架下表单令牌原理,较为详细的分析了thinkPHP表单令牌的原理、配置、错误原因与相应的解决方法。
thinlphp框架项目中开启表单令牌,要在配置文件中做如下配置
array(//是否开启令牌验证'TOKEN_ON'=>true,//令牌验证的表单隐藏字段名称'TOKEN_NAME'=>'__hash__',//令牌哈希验证规则 默认为MD5'TOKEN_TYPE'=>'md5',//令牌验证出错后是否重置令牌 默认为true'TOKEN_RESET'=>true);
编辑数据
$table= D('table');if(!$table->create()) {exit($this->error($table->getError()));}
TP框架中Model.class.php中的create方法
/***创建数据对象*@accesspublic*@parammixed $data创建数据*@paramstring $type状态*@returnmixed*/functioncreate($data='',$type=''){//表单令牌验证if(!$this->autoCheckToken($data)) {$this->error= L('_TOKEN_ERROR_');return false;}}
当autoCheckToken方法检测失败时会报错
//自动表单令牌验证functionautoCheckToken($data){//支持使用token(false)关闭令牌验证//如果在Action写了D方法,但没有对应的Model文件,那么$this->options为空if(isset($this->options['token']) && !$this->options['token'])return true;if(C('TOKEN_ON')) {$name= C('TOKEN_NAME');if(!isset($data[$name]) || !isset($_SESSION[$name])) {//令牌数据无效return false;}//令牌验证list($key,$value) =explode('_',$data[$name]);if($value&&$_SESSION[$name][$key] ===$value) {//防止重复提交unset($_SESSION[$name][$key]);//验证完成销毁sessionreturn true;}//开启TOKEN重置if(C('TOKEN_RESET'))unset($_SESSION[$name][$key]);return false;}return true;}
$_SESSION[$name]这个seesion变量,从生成令牌时说起,定位TokenBuildBehavior.class.php文件
//创建表单令牌functionbuildToken(){$tokenName= C('TOKEN_NAME');$tokenType= C('TOKEN_TYPE');if(!isset($_SESSION[$tokenName])) {$_SESSION[$tokenName] =array();}//标识当前页面唯一性$tokenKey=md5($_SERVER['REQUEST_URI']);if(isset($_SESSION[$tokenName][$tokenKey])) {//相同页面不重复生成session$tokenValue=$_SESSION[$tokenName][$tokenKey];}else{$tokenValue=$tokenType(microtime(TRUE));$_SESSION[$tokenName][$tokenKey] =$tokenValue;}$token='';return$token;}
这段代码主要是在TP开启表单验证的情况下,以TOKEN_NAME和当前URI的md5为健生成令牌值,
再在用户提交表单时,先验证下是否存在该session,没有则返回false,有则紧接着和表单字段TOKEN_NAME验证下,
如果一致先删除此session(作用时避免下次提交出先表单令牌错误),返回ture,否则返回false。
TP下表单提交出现令牌错误的原因
1. 在令牌开启的状态下,提交的表单中,没有TOKEN_NAME字段或是没有相应session
(当前提交表单环境下,没有生成相应session,这个主要是在用户提交后报错用户紧接着又刷新当前页面)
2. 有session变量,但前后值不一样
以上就是本文PHP -- ThinkPHP框架下表单令牌原理的全部内容,希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。