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开发负载均衡指南
Jul 17 PHP
php eval函数用法总结
Oct 31 PHP
PHP 转义使用详解
Jul 15 PHP
php计算两个日期时间差(返回年、月、日)
Jun 19 PHP
PHP+FastCGI+Nginx配置PHP运行环境
Aug 07 PHP
php将图片保存入mysql数据库失败的解决方法
Dec 27 PHP
php删除指定目录的方法
Apr 03 PHP
php生成数字字母的验证码图片
Jul 14 PHP
PHP那些琐碎的知识点(整理)
May 20 PHP
PHP封装的XML简单操作类完整实例
Nov 13 PHP
PHP封装的XML简单操作类完整实例
Nov 13 PHP
Laravel推荐使用的十个辅助函数
May 10 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中“简单工厂模式”实例代码讲解
2012/09/04 PHP
php-perl哈希算法实现(times33哈希算法)
2013/12/30 PHP
php使用ob_start()实现图片存入变量的方法
2014/11/14 PHP
在Laravel中实现使用AJAX动态刷新部分页面
2019/10/15 PHP
Convert Seconds To Hours
2007/06/16 Javascript
28个JS验证函数收集
2010/03/02 Javascript
JavaScript显示当然日期和时间即年月日星期和时间
2013/10/29 Javascript
javascript实现获取cookie过期时间的变通方法
2014/08/14 Javascript
javascript设置页面背景色及背景图片的方法
2015/12/29 Javascript
jQuery视差滚动效果网页实现方法经验总结
2016/09/29 Javascript
基于 D3.js 绘制动态进度条的实例详解
2018/02/26 Javascript
原生JS实现的雪花飘落动画效果
2018/05/03 Javascript
浅谈vue同一页面中拥有两个表单时,的验证问题
2018/09/18 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
2019/01/02 Javascript
js实现一个页面多个倒计时的3种方法
2019/02/25 Javascript
Python中dictionary items()系列函数的用法实例
2014/08/21 Python
python开发之tkinter实现图形随鼠标移动的方法
2015/11/11 Python
Python批量查询域名是否被注册过
2017/06/21 Python
python好玩的项目—色情图片识别代码分享
2017/11/07 Python
PyQT实现多窗口切换
2018/04/20 Python
Python自动发送邮件的方法实例总结
2018/12/08 Python
python协程之动态添加任务的方法
2019/02/19 Python
利用python中集合的唯一性实现去重
2020/02/11 Python
Python pip使用超时问题解决方案
2020/08/03 Python
本科生学习总结的自我评价
2013/10/02 职场文书
制衣厂各岗位职责
2013/12/02 职场文书
写给学生的新学期寄语
2014/01/18 职场文书
党支部书记岗位责任制
2014/02/11 职场文书
人民教师的自我评价分享
2014/02/21 职场文书
2014年大学生党课心得体会范文
2014/03/29 职场文书
优秀班组长事迹
2014/05/31 职场文书
农业项目建议书
2014/08/25 职场文书
文明旅游倡议书
2015/04/28 职场文书
个人业务学习心得体会
2016/01/25 职场文书
MySQL约束超详解
2021/09/04 MySQL
Android studio 简单计算器的编写
2022/05/20 Java/Android