Analysis and resolution of form token errors under ThinkPHP
How to solve the form token error under ThinkPHP? This article mainly introduces form token errors and solutions under ThinkPHP, and analyzes the principles, configurations, error causes and corresponding solutions of thinkPHP form tokens in more detail. Friends in need can refer to it. I hope it will be helpful to everyone.
The details are as follows:
During the development process of the project, I occasionally encountered the "Form Token Error" prompted by the system when adding and editing data. I didn't pay much attention to it at first until this afternoon. QA mentioned this issue to the bug system, and happened to have some spare time, so he followed the source code of TP3.13 and read it. After a few minutes, he knew the whole story.
To enable form tokens in a project, you usually need to make the following configuration in the configuration file
// 是否开启令牌验证 'TOKEN_ON' => true, // 令牌验证的表单隐藏字段名称 'TOKEN_NAME' => '__hash__', //令牌哈希验证规则 默认为MD5 'TOKEN_TYPE' => 'md5', //令牌验证出错后是否重置令牌 默认为true 'TOKEN_RESET' => true
Taking editing data as an example, there is usually a Model on the server side with field filtering rules and Action Write the data detection code, such as
$table = D('table'); if(!$table->create()){ exit($this->error($table->getError())); }
At this time, double-click create() on the IDE to locate the create method in Model.class.php in the TP framework
/** * 创建数据对象 但不保存到数据库 * @access public * @param mixed $data 创建数据 * @param string $type 状态 * @return mixed */ public function create($data='',$type='') { ……省略…… // 表单令牌验证 if(!$this->autoCheckToken($data)) { $this->error = L('_TOKEN_ERROR_'); return false; } ……省略…… }
When you see the code, you will understand that an error will be reported when the autoCheckToken method fails to detect, then continue to track this method
// 自动表单令牌验证 // TODO ajax无刷新多次提交暂不能满足 public function autoCheckToken($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]); // 验证完成销毁session return true; } // 开启TOKEN重置 if(C('TOKEN_RESET')) unset($_SESSION[$name][$key]); return false; } return true; }
After reading this code, you will find that $_SESSION[$name is included in the first judgment ], then where does this seesion variable come from? This has to start when generating the token, locating the TokenBuildBehavior.class.php file
// 创建表单令牌 private function buildToken() { $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 = '<input type="hidden" name="'.$tokenName.'" value="'.$tokenKey.'_'.$tokenValue.'" />'; return $token; }
This code is mainly used to open the form in TP In the case of verification, the token value is generated based on TOKEN_NAME and the md5 of the current URI. When the user submits the form, first verify whether the session exists. If not, return false. If yes, then verify with the form field TOKEN_NAME. If it is consistent, delete this session first (when used to avoid the form token error in the next submission), return true, otherwise return false.
ok, back to the topic, the reason why a token error occurs when submitting a form under TP, there are only two possibilities
1. Submit when the token is turned on In the form, there is no TOKEN_NAME field or no corresponding session (in the current submission form environment, no corresponding session is generated. This is mainly because an error is reported after the user submits and the user then refreshes the current page. At the same time, the editing page and the display page are in the same Method)
2. There is a session variable, but the before and after values are different
The reason why this error occurs in our project, you can look at the following configuration
return array ( 'TOKEN_ON' => 'false', 'TOKEN_NAME' => '__hash__', 'TOKEN_TYPE' => 'md5', 'TOKEN_RESET' => 'true', 'DB_FIELDTYPE_CHECK' => 'true' );
It should be written as Boolean The value of false, I don’t know which hero willfully wrote it as false as a string, then of course the judgment will be based on the logic of opening the form token, and in the project, adding, editing and display are all the same method. Once verified If an error occurs, the general program processing logic will return to the original interface, then it will be the same form as last time. Continuous submission of the same form is equivalent to repeated submission, then a "form token error" will be reported.
Related recommendations:
Detailed explanation of ThinkPHP’s behavioral extensions and plug-ins
Detailed explanation of how ThinkPHP generates and verifies verification codes
Detailed explanation of thinkphp5 URL and routing functions
The above is the detailed content of Analysis and resolution of form token errors under ThinkPHP. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.

In PHP, you can effectively prevent CSRF attacks by using unpredictable tokens. Specific methods include: 1. Generate and embed CSRF tokens in the form; 2. Verify the validity of the token when processing the request.
