ThinkPHP has a built-in form token verification function, which can effectively prevent remote submission of forms and other security protections.
Configuration parameters related to form token verification are:
'TOKEN_ON'=>true, // 是否开启令牌验证 'TOKEN_NAME'=>'__hash__', // 令牌验证的表单隐藏字段名称 'TOKEN_TYPE'=>'md5', //令牌哈希验证规则 默认为MD5
If the form token verification function is turned on, the system will automatically generate a hidden field named TOKEN_NAME in the template file with the form, and its value is a hash string generated by TOKEN_TYPE, which is used to implement the form. Automatic token verification.
The automatically generated hidden field is located before the form end mark. If you want to control the position of the hidden field, you can manually add the __TOKEN__ mark on the form page, and the system will automatically replace it when outputting the template. If form token verification is turned on and individual forms do not need to use the token verification function, you can add __NOTOKEN__ on the form page, and the system will ignore the token verification of the current form.
If there are multiple forms on the page, it is recommended to add the __TOKEN__ flag and ensure that only one form requires token verification.
The model class will automatically perform form token verification when creating the data object. If you do not use the create method to create the data object, you need to manually call the autoCheckToken method of the model to perform form token verification. If false is returned, it indicates a form token validation error. For example:
$User = M("User"); // 实例化User对象 // 手动进行令牌验证 if (!$User->autoCheckToken($_POST)){ // 令牌验证错误 }
A public template replacement function is defined in View.class.php of the ThinkPHP framework
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; }
The above if (C('TOKEN_ON')) is to determine the open status of token verification. If it is enabled, the buildFormToken() method is called, $_SESSION[$tokenName] = $tokenValue; In fact, it is to $_SESSION[ '__hash__'] assignment. If you don’t want to perform token verification, just add {__NOTOKEN__} before on the page, and it will be replaced by empty by the function.
The token verification function is defined in ThinkPHP’s Model.class.php class
// 表单令牌验证 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; }