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 相关文章推荐
php设计模式 State (状态模式)
Jun 26 PHP
怎样给PHP源代码加密?PHP二进制加密与解密的解决办法
Apr 22 PHP
php preg_replace替换实例讲解
Nov 04 PHP
Php中使用Select 查询语句的实例
Feb 19 PHP
Codeigniter注册登录代码示例
Jun 12 PHP
PHP文件锁定写入实例解析
Jul 14 PHP
PHPer 需要了解的 5 个 Composer 小技巧
Aug 18 PHP
PHP+MySQL删除操作实例
Jan 21 PHP
thinkPHP自定义类实现方法详解
Nov 30 PHP
Yii2配置Nginx伪静态的方法
May 05 PHP
laravel 解决路由除了根目录其他都404的问题
Oct 18 PHP
discuz论坛更换域名,详细文件修改步骤
Dec 09 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概述.
2006/10/09 PHP
JpGraph php柱状图使用介绍
2011/08/23 PHP
php最简单的删除目录与文件实现方法
2014/11/28 PHP
php生成shtml类用法实例
2014/12/09 PHP
php实现word转html的方法
2016/01/22 PHP
Laravel学习笔记之Artisan命令生成自定义模板的方法
2018/11/22 PHP
关于IE7 IE8弹出窗口顶上
2008/12/22 Javascript
Mootools 1.2教程 同时进行多个形变动画
2009/09/15 Javascript
jQuery对象数据缓存Cache原理及jQuery.data方法区别介绍
2013/04/07 Javascript
animate动画示例(泪奔的小孩)及stop和delay的使用
2013/05/06 Javascript
JQuery插件iScroll实现下拉刷新,滚动翻页特效
2014/06/22 Javascript
JavaScript中获取样式的原生方法小结
2014/10/08 Javascript
jQuery Ajax 异步加载显示等待效果代码分享
2016/08/01 Javascript
jQuery图片切换动画特效
2016/11/02 Javascript
jQuery Validate让普通按钮触发表单验证的方法
2016/12/15 Javascript
Vue开发过程中遇到的疑惑知识点总结
2017/01/20 Javascript
Bootstrap免费字体和图标网站(值得收藏)
2017/03/16 Javascript
用js屏蔽被http劫持的浮动广告实现方法
2017/08/10 Javascript
vue获取dom元素注意事项
2017/12/28 Javascript
Node.js 使用axios读写influxDB的方法示例
2018/10/26 Javascript
vue swipe自定义组件实现轮播效果
2019/07/03 Javascript
vue中的 $slot 获取插槽的节点实例
2019/11/12 Javascript
python3之微信文章爬虫实例讲解
2017/07/12 Python
Python轻量级ORM框架Peewee访问sqlite数据库的方法详解
2017/07/20 Python
利用python获取当前日期前后N天或N月日期的方法示例
2017/07/30 Python
pycharm中显示CSS提示的知识点总结
2019/07/29 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
Python的Lambda函数用法详解
2019/09/03 Python
Django实现网页分页功能
2019/10/31 Python
Python matplotlib修改默认字体的操作
2020/03/05 Python
浅谈keras使用预训练模型vgg16分类,损失和准确度不变
2020/07/02 Python
matplotlib绘制正余弦曲线图的实现
2021/02/22 Python
MyHeritage美国:家族史研究和DNA测试的领先服务
2019/05/27 全球购物
亲属关系公证书
2014/04/08 职场文书
毕业典礼演讲稿
2014/05/13 职场文书
python自动化操作之动态验证码、滑动验证码的降噪和识别
2021/08/30 Python