ThinkPHP令牌验证实例


Posted in PHP onJune 18, 2014

ThinkPHP内置了表单令牌验证功能,可以有效防止表单的远程提交等安全防护。
表单令牌验证相关的配置参数有:

'TOKEN_ON'=>true, // 是否开启令牌验证 
'TOKEN_NAME'=>'__hash__', // 令牌验证的表单隐藏字段名称 
'TOKEN_TYPE'=>'md5', //令牌哈希验证规则 默认为MD5

如果开启表单令牌验证功能,系统会自动在带有表单的模板文件里面自动生成以TOKEN_NAME为名称的隐藏域,其值则是TOKEN_TYPE方式生成的哈希字符串,用于实现表单的自动令牌验证。

自动生成的隐藏域位于表单Form结束标志之前,如果希望自己控制隐藏域的位置,可以手动在表单页面添加__TOKEN__ 标识,系统会在输出模板的时候自动替换。如果在开启表单令牌验证的情况下,个别表单不需要使用令牌验证功能,可以在表单页面添加__NOTOKEN__,则系统会忽略当前表单的令牌验证。

如果页面中存在多个表单,建议添加__TOKEN__标识,并确保只有一个表单需要令牌验证。

模型类在创建数据对象的同时会自动进行表单令牌验证操作,如果你没有使用create方法创建数据对象的话,则需要手动调用模型的autoCheckToken方法进行表单令牌验证。如果返回false,则表示表单令牌验证错误。例如:

$User = M("User"); // 实例化User对象 
// 手动进行令牌验证 
if (!$User->autoCheckToken($_POST)){ 
// 令牌验证错误 
}

在ThinkPHP框架的View.class.php里定义了一个公共的模板替换函数

protected function templateContentReplace($content) {
 // 系统默认的特殊变量替换
 $replace = array(
 '../Public' => APP_PUBLIC_PATH,// 项目公共目录
 '__PUBLIC__' => WEB_PUBLIC_PATH,// 站点公共目录
 '__TMPL__' => APP_TMPL_PATH, // 项目模板目录
 '__ROOT__' => __ROOT__, // 当前网站地址
 '__APP__' => __APP__, // 当前项目地址
 '__UPLOAD__' => __ROOT__.'/Uploads',
 '__ACTION__' => __ACTION__, // 当前操作地址
 '__SELF__' => __SELF__, // 当前页面地址
 '__URL__' => __URL__,
 '__INFO__' => __INFO__,
 );
 if(defined('GROUP_NAME'))
 {
 $replace['__GROUP__'] = __GROUP__;// 当前项目地址
 }
 if(C('TOKEN_ON')) {
 if(strpos($content,'{__TOKEN__}')) {
 // 指定表单令牌隐藏域位置
 $replace['{__TOKEN__}'] = $this->buildFormToken();
 }elseif(strpos($content,'{__NOTOKEN__}')){
 // 标记为不需要令牌验证
 $replace['{__NOTOKEN__}'] = '';
 }elseif(preg_match('/<\/form(\s*)>/is',$content,$match)) {
 // 智能生成表单令牌隐藏域
 $replace[$match[0]] = $this->buildFormToken().$match[0];
 }
 }
 // 允许用户自定义模板的字符串替换
 if(is_array(C('TMPL_PARSE_STRING')) )
 $replace = array_merge($replace,C('TMPL_PARSE_STRING'));
 $content = str_replace(array_keys($replace),array_values($replace),$content);
 return $content;
 }

上面的if(C('TOKEN_ON'))是对令牌验证的开启状态进行判断,若开启则调用buildFormToken()方法,$_SESSION[$tokenName] = $tokenValue; 其实就是给$_SESSION['__hash__']赋值。如果不想进行令牌验证,只要在页面的</form>之前加入{__NOTOKEN__}就行了,它会被函数替换成空。

在ThinkPHP的Model.class.php类里定义了令牌的验证函数

// 表单令牌验证
 if(C('TOKEN_ON') && !$this->autoCheckToken($data)) {
 $this->error = L('_TOKEN_ERROR_');
 return false;
 }

 // 自动表单令牌验证
 public function autoCheckToken($data) {
 $name = C('TOKEN_NAME');
 if(isset($_SESSION[$name])) {
 // 当前需要令牌验证
 if(empty($data[$name]) || $_SESSION[$name] != $data[$name]) {
 // 非法提交
 return false;
 }
 // 验证完成销毁session
 unset($_SESSION[$name]);
 }
 return true;
 }
PHP 相关文章推荐
表单复选框向PHP传输数据的代码
Nov 13 PHP
PHP写入WRITE编码为UTF8的文件的实现代码
Jul 07 PHP
关于js与php互相传值的介绍
Jun 25 PHP
PHP无限分类(树形类)
Sep 28 PHP
curl实现站外采集的方法和技巧
Jan 31 PHP
php调用c接口无错版介绍
Mar 11 PHP
php中的四舍五入函数代码(floor函数、ceil函数、round与intval)
Jul 14 PHP
php批量删除cookie的简单实现方法
Jan 26 PHP
php随机抽奖实例分析
Mar 04 PHP
php实现网站文件批量压缩下载功能
Oct 28 PHP
thinkphp5 加载静态资源路径与常量的方法
Dec 24 PHP
ThinkPHP3.1.2 使用cli命令行模式运行的方法
Apr 14 PHP
Smarty局部缓存的几种方法简介
Jun 17 #PHP
smarty模板局部缓存方法使用示例
Jun 17 #PHP
CodeIgniter CLI模式简介
Jun 17 #PHP
CI框架在CLI下执行占用内存过大问题的解决方法
Jun 17 #PHP
CI框架自动加载session出现报错的解决办法
Jun 17 #PHP
Thinkphp模板中截取字符串函数简介
Jun 17 #PHP
CI框架中zip类应用示例
Jun 17 #PHP
You might like
PHP中计算字符串相似度的函数代码
2012/12/29 PHP
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
PHP中Header使用的HTTP协议及常用方法小结
2014/11/04 PHP
ThinkPHP框架里隐藏index.php
2016/04/12 PHP
Python中使用django form表单验证的方法
2017/01/16 PHP
PHP获取当前URL路径的处理方法(适用于多条件筛选列表)
2017/02/10 PHP
JS类中定义原型方法的两种实现的区别
2007/03/08 Javascript
Javascript &amp; DHTML 实例编程(教程)DOM基础和基本API
2007/06/02 Javascript
javascript prototype 原型链
2009/03/12 Javascript
js里怎么取select标签里的值并修改
2012/12/10 Javascript
table对象中的insertRow与deleteRow使用示例
2014/01/26 Javascript
HTML页面弹出居中可拖拽的自定义窗口层
2014/05/07 Javascript
JavaScript自定义函数实现查找两个字符串最长公共子串的方法
2016/11/24 Javascript
Javascript的this用法
2017/01/16 Javascript
简单实现js悬浮导航效果
2017/02/05 Javascript
JS实现匀速与减速缓慢运动的动画效果封装示例
2018/08/27 Javascript
Vue element-ui父组件控制子组件的表单校验操作
2020/07/17 Javascript
[02:08]2018年度CS GO枪械皮肤设计大赛优秀作者-完美盛典
2018/12/16 DOTA
Python2实现的LED大数字显示效果示例
2017/09/04 Python
Python爬虫_城市公交、地铁站点和线路数据采集实例
2018/01/10 Python
python多线程并发实例及其优化
2019/06/27 Python
python Django的web开发实例(入门)
2019/07/31 Python
HTML+CSS3+JS 实现的下拉菜单
2020/11/25 HTML / CSS
戴尔美国官网:Dell
2016/08/31 全球购物
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
美国领先的低折扣旅行网站:Hotwire
2019/01/19 全球购物
单位实习证明怎么写
2014/01/17 职场文书
入党思想汇报怎么写
2014/04/03 职场文书
初中生期末评语大全
2014/04/24 职场文书
公司租房协议书范本
2014/10/08 职场文书
2015年试用期工作总结
2014/12/12 职场文书
五好家庭事迹材料
2014/12/20 职场文书
给学校的建议书400字
2015/09/14 职场文书
MySQL为id选择合适的数据类型
2021/06/07 MySQL
Nginx动静分离配置实现与说明
2022/04/07 Servers
mysql使用 not int 子查询隐含陷阱
2022/04/12 MySQL