Provides various official and user-released code examples. For code reference, you are welcome to exchange and learn about ajax requests. create verifies the token and destroys the token session. After ajax submits the request again, token verification fails. There are two solutions:
1. In the Model. class. php core class, add the parameter of whether to destroy the token session. When it is an ajax request, do not destroy the session. [unsafe]
2. After the session is destroyed in create, generate a new token, return the new token to the ajax callback function, and modify the page token in the callback function, in this way, the latest token is used for the next request.
Here, I will share my thoughts. If there are any problems, I hope to point out:
Problem:
Token verification is used for normal form submission. When the network is slow, redundant data cannot be submitted and stored repeatedly. However, an error is reported when ajax is used for the second submission.
Cause:
After you submit a token Using ajax, when you use the create method in the Controller to verify the data, the token is destroyed and the data is saved through verification,
However, a new token cannot be generated. The old token is submitted again on the page and cannot be passed during the create method verification. Therefore, an error is returned. Why cannot I generate a new token after ajax is submitted? How does the Create method verify the token and destroy the token? Where is the token stored? With these questions, view the source code
Analysis:
Token Generation:
The Thinkphp framework starts from the beginning of the program, requests-controller processing-page output, and uses a large number of behaviors to execute the program using tags similar to events (a tag can carry many behaviors.
When the token is enabled, a hidden domain named _ hash _ is generated on the page. However, we only use the form tag and do not add this hidden domain, it must be added by the system. When will it be added? It is very likely that it will be replaced by a template. Check thinkphp's behavior. There is a TokenBuildBehavior creation token in it. When will this behavior be called? Because the execution of thinkphp system behavior is configured in tags, it is indeed executed in the view_filter event. From the word, it can be seen that it is very related to the View class. Product View core View. class. php
In the fetch method, that is, when the display is executed, the token generated when the template is output.
Open the Create Token class, and you can see the token settings, name encryption, and so on. The generated token is 1. The request page url is encrypted with md5 and then connected with an underscore
2. Time encryption [this is what we see on the page ]. The two encrypted strings are respectively saved as keys and values in $ _ session ['_ hash _'] [if you have not modified the token name ]. After the token is generated, the system determines whether to enable the token and whether to write the hidden domain of the _ hash _ name on the page. If not written, the system can only add the token through the regular expression matching form.
Protected $ options = array (
'Token _ on' => false, // enable TOKEN Verification
'Token _ name' => '_ hash _', // NAME of the hidden field in the form for TOKEN Verification
'Token _ type' => 'md5', // TOKEN verification hash rule
'Token _ reset' => true, // whether to RESET after the TOKEN is incorrect
);
'View _ filter' => array (
'Contentreplicase', // template output replacement
'Tokenbuilt', // form token
'Writehtmlcache', // write to static Cache
'Showruntime', // Run Time Display
),
Token Verification:
If a token is generated, how can we prevent repeated submission?
Thinkphp has done a lot of work using the create method, including token verification, which can be passed through the core class model. class. PHP File Viewing, but the create method does not really write database operations, save the work to add and other methods. $ Data =$ _ POST; the submitted data is handed over to the create method. Therefore, you do not need to manually PASS Parameters when using this method. Separate the submitted data with strings. The separated Data includes the key and value. If the data saved in the session matches the submitted data, the session is verified and destroyed, if the token does not match, false is returned and the token is destroyed (if the reset token is enabled ]. The actual save operation add is called only after the create method is verified. Therefore, if the second commit is performed before the data is saved, the session is cleared, if the verification fails, a token error is reported.
Now it is clear that after the ajax request, the controller performs the create verification and destroys the session, but there is no chance to generate a new token, because the new token is called to create the token when the output page is generated.
Solution:
1. In Model. class. in the php core class, add the parameter of whether to destroy the token session. When it is an ajax request, the session is not destroyed [unsafe] 2. After the session is destroyed in create, generate a new token, return the newly generated token to the ajax callback function and modify the page token in the callback function. In this way, the latest token is used for the next request.
The first method is too simple. The second method is described here.
For the code, see:
Create an action class that only generates tokens and does not replace the template [it is best to inherit the system's token to create an action class, so that you do not need to define some variables again ], create your own behavior tag [add 'create _ token' => array ('tokenonly') in tags,]. After the create method is verified, call the behavior class that creates the token, and return the generated token to the ajax callback function.
$ Token = '';
Tag (create_token, $ token );
Echo json_encode (array ('flag' => "OK", 'Token' => $ token ));
On the view page, modify the value of the _ hash _ hidden field on the js page to the latest token.
$ (_ Hash _). val (data. token );
Complete
For behavior classes that only create tokens, inherit the system token to create behavior classes and remove the content with tags. For code reference:
Defined ('Think _ path') or exit ();
/**
* Only the generated form token is returned.
*/
Class TokenOnlyBehavior extends TokenBuildBehavior {
Public function run (& $ content ){
$ This-> buildToken (& $ content );
}
// Create a form token
Private function buildToken (& $ content ){
$ TokenName = C ('token _ name ');
$ TokenType = C ('token _ type ');
If (! Isset ($ _ SESSION [$ tokenName]) {
$ _ SESSION [$ tokenName] = array ();
}
// Identifies the uniqueness of the current page
$ TokenKey = md5 ($ _ SERVER ['request _ URI ']);
If (isset ($ _ SESSION [$ tokenName] [$ tokenKey]) {// No duplicate session is generated on the same page.
$ TokenValue = $ _ SESSION [$ tokenName] [$ tokenKey];
} Else {
$ TokenValue = $ tokenType (microtime (TRUE ));
$ _ SESSION [$ tokenName] [$ tokenKey] = $ tokenValue;
}
$ Content = $ tokenKey. '_'. $ tokenValue;
}
}
AD: truly free, domain name + VM + enterprise mailbox = 0 RMB