ThinkPHP5.1表单令牌Token失效问题的解决


Posted in PHP onMarch 22, 2019

前言

ThinkPHP出于安全的考虑增加了表单令牌Token,由于通过Ajax异步更新数据仅仅部分页面刷新数据,就导致了令牌Token不能得到更新,紧接着的第二次新建或更新数据(提交表单时)失败——不能通过令牌的验证。

当然了,最简单的办法就是刷新整个页面,就导致了异步刷新的无意义!在网上搜寻了很多,有好几种方法;看完觉得有一个最好:

Ajax异步动态请求创建新令牌并更新到本地
主要思路:在每次发送表单结束后(不管成功与否)通过Ajax异步请求一个新的表单令牌并保存到表单隐藏域中,下次提交表单就使用新的表单令牌去通过。

最终的效果如下:

ThinkPHP5.1表单令牌Token失效问题的解决
V2.5.0.png

主要分成三步:

第一步:在Index控制器下创建生成Token的方法

之所以选择在Index控制器下创建,主要考虑在整个admin(后台)可以方便的引用该方法,不需要每次都根据控制器找寻相应的方法。也就是说,该方法其他控制器都可以引用!

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

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

第二步:在Javascript中创建Ajax获取新令牌

由于后台生成新令牌的地址已经固定了,也就是:
/admin/Index/,因此通过jQuery的Get方法容易获取该令牌!

// 获取新Token并更新
function getNewToken() {
 $.get("/admin/Index/getToken", function(data) {
  document.getElementById("__token__").value = data;
 });
}

第三步:在Html页面中创建隐藏域保存令牌

其实在ThinkPHP的表单示例代码中已经有了该代码。页面第一次加载时的令牌Token是随着页面分配的,后面的令牌就是通过Ajax获取的!

<!-- 隐藏区域 -->
<input type="hidden" id="__token__" name="__token__" value="{$Request.token}" />

最后,我们就可以在javascript的相应提交表单的地方增加语句申请新令牌了!举例,下面的示例代码在提交后不管成功与否都申请了新的令牌。

/**
 * Ajax动态更新数据并异步刷新页面
 * @Author DuDongHua
 * @DateTime 2018-04-28T21:21:23+0800
 * @param {对象} Button  表单按钮对象
 * @param {文本} Modal  模块
 * @param {文本} Controller 控制器
 * @param {文本} Action  方法
 * @param {文本} Location Ajax加载页面的位置id
 * 使用方法:表单对象不用提交的任何设置,提交假按钮<a>设置onclick即可
 * 注意:
 *  1. 在javascript中拼接Thinkphp5的URL地址,不需要"{:url('" + Modal + "/" + Controller + "/" + Page + "')}方法
 *   只需要直接拼接地址即可,如:var MeURL = '/'+Modal+'/'+Controller+'/'+Page;
 */
function EditData(Button,Modal,Controller,Action,Location,Page){
 // 设置默认参数
 var Modal  = arguments[1] ? arguments[1] : "admin";  // 模块名
 var Controller = arguments[2] ? arguments[2] : "index";  // 控制器
 var Action  = arguments[3] ? arguments[3] : "editData"; // 方法名
 var Location = arguments[4] ? arguments[4] : "content"; // Ajax加载页面的位置id
 var Page  = arguments[5] ? arguments[5] : "index";  // Ajax加载页面控制器中的方法
 // 生成本页面的url用于更新后异步刷新
 var MeURL = '/'+Modal+'/'+Controller+'/'+Page;
 setLoaderIn(true); //打开加载图标
 // 异步请求数据
 $.ajax({
  url: '/'+Modal+'/'+Controller+'/'+Action,
  type: 'POST',
  data: $(Button).closest("form").serialize(), //表单序列化
  dataType: 'json',
  success: function(data){
   // 更新页面并提示
   // window.location.reload(); //当加载整个页面时有效但ajax更新时加载到主页
   loadAjaxHTML(MeURL,Location);
   showMsg(data.msg);
   setLoaderIn(false); //关闭加载图标
   getNewToken();  // 获取新Token
  },
  error:function(XMLHttpRequest, textStatus, errorThrown){
   showMsg(XMLHttpRequest.status+" "+XMLHttpRequest.readyState,textStatus,"red","#f60");
   getNewToken(); // 获取新Token
  }
 });
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
用Zend Encode编写开发PHP程序
Oct 09 PHP
实现“上一页”和“下一页按钮
Oct 09 PHP
php在字符串中查找另一个字符串
Nov 19 PHP
通过PHP CLI实现简单的数据库实时监控调度
Jul 01 PHP
php计算当前程序执行时间示例
Apr 24 PHP
一个PHP的ZIP压缩类分享
May 04 PHP
Yii实现简单分页的方法
Apr 29 PHP
php基于curl实现的股票信息查询类实例
Nov 11 PHP
PHP无限极分类函数的实现方法详解
Apr 15 PHP
php之header的不同用法总结(实例讲解)
Nov 28 PHP
php-fpm超时时间设置request_terminate_timeout资源问题分析
Sep 27 PHP
PHP实现rar解压读取扩展包小结
Jun 03 PHP
PHP iconv()函数字符编码转换的问题讲解
Mar 22 #PHP
PHP里的$_GET数组介绍
Mar 22 #PHP
PHP匿名函数(闭包函数)详解
Mar 22 #PHP
PHP利用递归函数实现无限级分类的方法
Mar 22 #PHP
用PHP的反射实现委托模式的讲解
Mar 22 #PHP
PHP读取目录树的实现方法分析
Mar 22 #PHP
针对PHP开发安全问题的相关总结
Mar 22 #PHP
You might like
使用CodeIgniter的类库做图片上传
2014/06/12 PHP
php面向对象中static静态属性和静态方法的调用
2015/02/08 PHP
php实现httpRequest的方法
2015/03/13 PHP
PHP中抽象类和抽象方法概念与用法分析
2016/05/24 PHP
thinkPHP5框架路由常用知识点汇总
2019/09/15 PHP
JS实现在Repeater控件中创建可隐藏区域的代码
2010/09/16 Javascript
ExtJs使用总结(非常详细)
2012/03/22 Javascript
一个基于jquery的文本框记数器
2012/09/19 Javascript
按下Enter焦点移至下一个控件的实现js代码
2013/12/11 Javascript
Chrome下ifame父窗口调用子窗口的问题示例探讨
2014/03/17 Javascript
ECMAScript 5严格模式(Strict Mode)介绍
2015/03/02 Javascript
jquery插件EasyUI中form表单提交实例分享
2016/01/11 Javascript
JQuery中attr属性和jQuery.data()学习笔记【必看】
2016/05/18 Javascript
JavaScript学习笔记整理_setTimeout的应用
2016/09/19 Javascript
jquery实现多次上传同一张图片
2017/01/09 Javascript
全面总结Javascript对数组对象的各种操作
2017/01/22 Javascript
JS判断一个数是否是水仙花数
2017/06/11 Javascript
JavaScript实现一个简易的计算器实例代码
2018/05/10 Javascript
layui多图上传实现删除功能的例子
2019/09/23 Javascript
javascript实现点击按钮切换轮播图功能
2020/09/23 Javascript
ant-design-vue中的select选择器,对输入值的进行筛选操作
2020/10/24 Javascript
Python中几个比较常见的名词解释
2015/07/04 Python
Python中利用Scipy包的SIFT方法进行图片识别的实例教程
2016/06/03 Python
Python 常用的安装Module方式汇总
2017/05/06 Python
通过Pandas读取大文件的实例
2018/06/07 Python
Python3实现定时任务的四种方式
2019/06/03 Python
Python企业编码生成系统之系统主要函数设计详解
2019/07/26 Python
jupyter notebook读取/导出文件/图片实例
2020/04/16 Python
解决c++调用python中文乱码问题
2020/07/29 Python
应届生人事助理求职信
2013/11/09 职场文书
《小池塘》教学反思
2014/02/28 职场文书
在教室放鞭炮的检讨书
2014/09/28 职场文书
查摆剖析材料范文
2014/09/30 职场文书
大学生党课心得体会
2016/01/07 职场文书
初任公务员培训心得体会
2016/01/08 职场文书
五年级作文之想象作文
2019/10/30 职场文书