Solution to the problem of token invalidation in thinkphp5.1 form

Time:2020-6-28

preface

ThinkPHP added the form token token for the sake of security. Because the data is updated asynchronously through Ajax and only part of the page refreshes the data, the token token cannot be updated. The next new or updated data (when submitting the form) fails – it cannot pass the token verification.

Of course, the easiest way is to refresh the entire page, which leads to the meaningless asynchronous refresh! I have searched a lot on the Internet, and there are several ways. After reading it, I think there is one best way:

Ajax asynchronous dynamic request to create new token and update to local
Main idea: request a new form token asynchronously through Ajax after sending the form (no matter successful or not) and save it in the hidden field of the form, and use the new form token to pass the next time the form is submitted.

The final effect is as follows:


V2.5.0.png

It is divided into three steps

Step 1: create a token generation method under the index controller

The main reason for choosing to create under index controller is that the method can be easily referenced in the whole admin (background), and it is not necessary to find the corresponding method according to the controller every time. That is to say, other controllers of this method can reference!

<?php
namespace app\admin\controller;
use think\Controller;

class Index extends Valid {
 //Generate token function
 public function getToken() {
  $request = \think\facade\Request::instance();
  echo $request->token();
 }
}

Step 2: create Ajax in JavaScript to get a new token

Because the address of the new token generated in the background has been fixed, that is:
/Admin / index /, so it’s easy to get the token through jQuery’s get method!

//Get new token and update
function getNewToken() {
 $.get("/admin/Index/getToken", function(data) {
  document.getElementById("__token__").value = data;
 });
}

Step 3: create a hidden domain save token in the HTML page

In fact, this code already exists in the form sample code of ThinkPHP. The token token when the page is first loaded is allocated along with the page, and the latter token is obtained through Ajax!

<! -- hidden area -- >
<input type="hidden" name="__token__" value="{$Request.token}" />

Finally, we can add a statement to apply for a new token in the corresponding submission form of JavaScript! For example, the following example code applies for a new token whether it succeeds or not after submission.

/**
 *Ajax updates data dynamically and refreshes pages asynchronously
 * @Author DuDongHua
 * @DateTime 2018-04-28T21:21:23+0800
 *@ param {object} button form button object
 *@ param {text} modal module
 *@ param {text} controller
 *@ param {text} action method
 *Location ID of the @ param {text} location Ajax load page
 *Usage: the form object does not need to submit any settings. The submit false button < a > set onclick
 *Note:
 *1. The method "{: URL ('" + modal + "/" + controller + "/" + page + "')}" is not needed to splice the URL address of thinkp5 in JavaScript
 *You only need to splice addresses directly, for example: VAR meurl = '/' + modal + '/' + controller + '/' + page;
 */
function EditData(Button,Modal,Controller,Action,Location,Page){
 //Set default parameters
 Var modal = arguments [1]? Arguments [1]: "admin"; // module name
 Var controller = arguments [2]? Arguments [2]: "index"; // controller
 Var action = arguments [3]? Arguments [3]: "editdata"; // method name
 Var location = arguments [4]? Arguments [4]: "content"; // the location ID of the Ajax load page
 Var page = arguments [5]? Arguments [5]: "index"; // Ajax loads methods in page controller
 //Generate the URL of this page for asynchronous refresh after update
 var MeURL = '/'+Modal+'/'+Controller+'/'+Page;
 Setloaderin (true); // open the load Icon
 //Asynchronous request data
 $.ajax({
  url: '/'+Modal+'/'+Controller+'/'+Action,
  type: 'POST',
  Data: $(button). Closest ("form"). Serialize(), // form serialization
  dataType: 'json',
  success: function(data){
   //Update page and prompt
   // window.location.reload (); // valid when loading the entire page but loaded to the home page when Ajax updates
   loadAjaxHTML(MeURL,Location);
   showMsg(data.msg);
   Setloaderin (false); // close load Icon
   Getnewtoken(); // get the new token
  },
  error:function(XMLHttpRequest, textStatus, errorThrown){
   showMsg(XMLHttpRequest.status+" "+XMLHttpRequest.readyState,textStatus,"red","#f60");
   Getnewtoken(); // get the new token
  }
 });
}

summary

The above is the whole content of this article. I hope that the content of this article has some reference learning value for your study or work. Thank you for your support for developepaer.

Recommended Today

Kafka learning materials

Kafka 1、 Benefits of message middleware 1. Decoupling It allows you to extend or modify processes on both sides independently, as long as you make sure they comply with the same interface constraints. It would be a great waste to put resources on standby to handle such peak visits. The use of message queue can […]