热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ThinkPHP表单令牌验证功能

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

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

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

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

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

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

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

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

在ThinkPHP框架的View.class.php里定义了一个公共的模板替换函数,PHP代码如下:

  1. protected function templateContentReplace($content) { 
  2.         // 系统默认的特殊变量替换 
  3.         $replace =  array
  4.             '../Public'     => APP_PUBLIC_PATH,// 项目公共目录 
  5.             '__PUBLIC__'    => WEB_PUBLIC_PATH,// 站点公共目录 
  6.             '__TMPL__'      => APP_TMPL_PATH,  // 项目模板目录 
  7.             '__ROOT__'      => __ROOT__,       // 当前网站地址 
  8.             '__APP__'       => __APP__,        // 当前项目地址 
  9.             '__UPLOAD__'    => __ROOT__.'/Uploads'
  10.             '__ACTION__'    => __ACTION__,     // 当前操作地址 
  11.             '__SELF__'      => __SELF__,       // 当前页面地址 
  12.             '__URL__'       => __URL__, 
  13.             '__INFO__'      => __INFO__, 
  14.         ); 
  15.         if(defined('GROUP_NAME')) 
  16.         { 
  17.             $replace['__GROUP__'] = __GROUP__;// 当前项目地址 
  18.         } 
  19.         if(C('TOKEN_ON')) { 
  20.             if(strpos($content,'{__TOKEN__}')) { 
  21.                 // 指定表单令牌隐藏域位置 
  22.                 $replace['{__TOKEN__}'] =  $this->buildFormToken(); 
  23.             }elseif(strpos($content,'{__NOTOKEN__}')){ 
  24.                 // 标记为不需要令牌验证 
  25.                 $replace['{__NOTOKEN__}'] =  ''
  26.             }elseif(preg_match(&#39;/<\/form(\s*)>/is&#39;,$content,$match)) { 
  27.                 // 智能生成表单令牌隐藏域 
  28.                 $replace[$match[0]] = $this->buildFormToken().$match[0]; 
  29.             } 
  30.         } 
  31.         // 允许用户自定义模板的字符串替换 
  32.         if(is_array(C(&#39;TMPL_PARSE_STRING&#39;)) ) 
  33.             $replace =  array_merge($replace,C(&#39;TMPL_PARSE_STRING&#39;)); 
  34.         $content = str_replace(array_keys($replace),array_values($replace),$content); 
  35.         return $content
  36.     } 

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

在ThinkPHP的Model.class.php类里定义了令牌的验证函数,PHP代码如下:

  1. // 表单令牌验证 
  2.         if(C(&#39;TOKEN_ON&#39;) && !$this->autoCheckToken($data)) { 
  3.             $this->error = L(&#39;_TOKEN_ERROR_&#39;); 
  4.             return false; 
  5.         } 
  6.  
  7.   // 自动表单令牌验证 
  8.     public function autoCheckToken($data) { 
  9.         $name   = C(&#39;TOKEN_NAME&#39;); 
  10.         if(isset($_SESSION[$name])) { 
  11.             // 当前需要令牌验证 
  12.             if(emptyempty($data[$name]) || $_SESSION[$name] != $data[$name]) { 
  13.                 // 非法提交 
  14.                 return false; 
  15.             } 
  16.             // 验证完成销毁session 
  17.             unset($_SESSION[$name]); 
  18.         } 
  19.         return true; 
  20.     } 

推荐阅读
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 使用Numpy实现无外部库依赖的双线性插值图像缩放
    本文介绍如何仅使用Numpy库,通过双线性插值方法实现图像的高效缩放,避免了对OpenCV等图像处理库的依赖。文中详细解释了算法原理,并提供了完整的代码示例。 ... [详细]
  • 本文详细分析了JSP(JavaServer Pages)技术的主要优点和缺点,帮助开发者更好地理解其适用场景及潜在挑战。JSP作为一种服务器端技术,广泛应用于Web开发中。 ... [详细]
  • Valve 发布 Steam Deck 的新版 Windows 驱动程序
    Valve 最新发布了针对 Steam Deck 掌机的 Windows 驱动程序,旨在提升其在 Windows 环境下的兼容性、安全性和性能表现。 ... [详细]
  • 三星W799在2011年的表现堪称经典,以其独特的双屏设计和强大的功能引领了双模手机的潮流。本文详细介绍其配置、功能及锁屏设置。 ... [详细]
  • 本文探讨了Hive中内部表和外部表的区别及其在HDFS上的路径映射,详细解释了两者的创建、加载及删除操作,并提供了查看表详细信息的方法。通过对比这两种表类型,帮助读者理解如何更好地管理和保护数据。 ... [详细]
  • 本文总结了汇编语言中第五至第八章的关键知识点,涵盖间接寻址、指令格式、安全编程空间、逻辑运算指令及数据重复定义等内容。通过详细解析这些内容,帮助读者更好地理解和应用汇编语言的高级特性。 ... [详细]
  • 数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
    本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ... [详细]
  • 优化版Windows 10 LTSC 21H2企业版:适用于低内存设备
    此版本为经过优化的Windows 10 LTSC 21H2企业版,特别适合低内存配置的计算机。它基于官方版本进行了精简和性能优化,确保在资源有限的情况下依然能够稳定运行。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
author-avatar
小呀么小果冻
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有