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 相关文章推荐
如何去掉文章里的 html 语法
Oct 09 PHP
Mysql和网页显示乱码解决方法集锦
Mar 27 PHP
php下使用以下代码连接并测试
Apr 09 PHP
很好用的PHP数据库类
May 27 PHP
php中的观察者模式
Mar 24 PHP
PHP生成器简单实例
May 13 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
Dec 24 PHP
利用PHP命令行模式采集股票趋势信息
Aug 09 PHP
php、java、android、ios通用的3des方法(推荐)
Sep 09 PHP
实例讲解PHP验证邮箱是否合格
Jan 28 PHP
PHP bin2hex()函数基础实例讲解
Feb 11 PHP
Yii框架中用response保存cookie,用request读取cookie的原理解析
Sep 04 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
聊天室php&amp;mysql(四)
2006/10/09 PHP
实用函数8
2007/11/08 PHP
php微信开发之批量生成带参数的二维码
2016/06/26 PHP
php防止sql注入的方法详解
2017/02/20 PHP
php利用ob_start()清除输出和选择性输出的方法
2018/01/18 PHP
laravel框架关于搜索功能的实现
2018/03/15 PHP
Jquery实现点击切换图片并隐藏显示内容(2种方法实现)
2013/04/11 Javascript
JS getAttribute和setAttribute(取得和设置属性)的使用介绍
2013/07/10 Javascript
变量声明时命名与变量作为对象属性时命名的区别解析
2013/12/06 Javascript
你未必知道的JavaScript和CSS交互的5种方法
2014/04/02 Javascript
prototype.js常用函数详解
2016/06/18 Javascript
Extjs让combobox写起来简洁又漂亮
2017/01/05 Javascript
深入理解vue路由的使用
2017/03/24 Javascript
jquery仿微信聊天界面
2017/05/06 jQuery
自定义vue全局组件use使用、vuex的使用详解
2017/06/14 Javascript
AngularJS 应用模块化的使用
2018/04/04 Javascript
解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
2020/04/21 Javascript
python自定义解析简单xml格式文件的方法
2015/05/11 Python
Python运算符重载详解及实例代码
2017/03/07 Python
python+matplotlib实现鼠标移动三角形高亮及索引显示
2018/01/15 Python
在Python中使用Neo4j的方法
2019/03/14 Python
PyTorch之图像和Tensor填充的实例
2019/08/18 Python
详解python内置常用高阶函数(列出了5个常用的)
2020/02/21 Python
python使用梯度下降和牛顿法寻找Rosenbrock函数最小值实例
2020/04/02 Python
欧洲高端品牌直销店:Fashionesta
2016/08/31 全球购物
英国顶级足球鞋的领先零售商:Lovell Soccer
2019/08/27 全球购物
公安机关查摆剖析材料
2014/10/10 职场文书
2015年党员公开承诺书范文
2015/01/22 职场文书
考察邀请函范文
2015/01/31 职场文书
关于学习的决心书
2015/02/05 职场文书
2015年感恩母亲节的演讲稿
2015/03/18 职场文书
2015年客服工作总结范文
2015/04/02 职场文书
《火烧云》教学反思
2016/02/23 职场文书
求职自荐信该如何书写?
2019/06/24 职场文书
Windows Server 2012 修改远程默认端口3389的方法
2022/04/28 Servers