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 相关文章推荐
Windows下PHP5和Apache的安装与配置
Sep 05 PHP
php的header和asp中的redirect比较
Oct 09 PHP
PHP 编程的 5个良好习惯
Feb 20 PHP
PHP中获取文件扩展名的N种方法小结
Feb 27 PHP
mysql 查询指定日期时间内sql语句实现原理与代码
Dec 16 PHP
基于Discuz security.inc.php代码的深入分析
Jun 03 PHP
php stream_get_meta_data返回值
Sep 29 PHP
一个不易被发现的PHP后门代码解析
Jul 05 PHP
WordPress导航菜单的滚动和淡入淡出效果的实现要点
Dec 14 PHP
Yii调试查看执行SQL语句的方法
Jul 15 PHP
PHP生成随机数的方法总结
Mar 01 PHP
PHP生成二维码与识别二维码的方法详解【附源码下载】
Mar 07 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
php设计模式 Chain Of Responsibility (职责链模式)
2011/06/26 PHP
浅谈本地WAMP环境的搭建
2015/05/13 PHP
php简单解析mysqli查询结果的方法(2种方法)
2016/06/29 PHP
flexigrid 类似ext grid的JS表格代码
2010/07/17 Javascript
给事件响应函数传参数的四种方式小结
2013/12/05 Javascript
jquery查找父元素、子元素(个人经验总结)
2014/04/09 Javascript
手写的一个兼容各种浏览器的javascript getStyle函数(获取元素的样式)
2014/06/06 Javascript
node.js中的fs.truncate方法使用说明
2014/12/15 Javascript
JS简单编号生成器实现方法(附demo源码下载)
2016/04/05 Javascript
JSON字符串转换JSONObject和JSONArray的方法
2016/06/03 Javascript
ES6学习笔记之Set和Map数据结构详解
2017/04/07 Javascript
JavaScript实现二叉树的先序、中序及后序遍历方法详解
2017/10/26 Javascript
angularJs中$http获取后台数据的实例讲解
2018/08/08 Javascript
解决element-ui中下拉菜单子选项click事件不触发的问题
2018/08/22 Javascript
js简单的分页器插件代码实例
2019/09/11 Javascript
vue 组件销毁并重置的实现
2020/01/13 Javascript
js面向对象之实现淘宝放大镜
2020/01/15 Javascript
jQuery HTML设置内容和属性操作实例分析
2020/05/20 jQuery
python模拟登陆Tom邮箱示例分享
2014/01/13 Python
python自动化测试实例解析
2014/09/28 Python
python xlsxwriter库生成图表的应用示例
2018/03/16 Python
python实现彩色图转换成灰度图
2019/01/15 Python
python将数组n等分的实例
2019/12/02 Python
基于python实现上传文件到OSS代码实例
2020/05/09 Python
Django中使用Json返回数据的实现方法
2020/06/03 Python
对Pytorch 中的contiguous理解说明
2021/03/03 Python
css3学习之2D转换功能详解
2016/12/23 HTML / CSS
世界顶级俱乐部的官方球衣和套装:Subside Sports
2018/04/22 全球购物
城市轨道专业个人求职信范文
2013/09/23 职场文书
医学毕业生自我鉴定
2013/10/30 职场文书
大学生年度自我鉴定
2013/10/31 职场文书
电话销售经理岗位职责
2013/12/07 职场文书
蛋糕店的商业计划书范文
2014/01/27 职场文书
报纸媒体创意广告词
2014/03/17 职场文书
8和9的加减法教学反思
2014/05/01 职场文书
项目建议书模板
2014/05/12 职场文书