PHP表单TOKEN防止重复提交

一 简介

1. 什么是表单token?
Token(人家就叫这名,记住就行)是服务端生成的一串字符串,以作客户端进行请求的一个令牌和依据。
2. 表单token用来干什么?
第一:防止提交表单是为外部提交。也叫(跨站点请求伪造)。
第二:防止表单重复提交,造成数据错乱。
3. 表单token的实现原理是什么?
在用户进入任何一个表单页面的时候,服务器端就会生成一段针对该用户的唯一token码,同时该token码会保存到该用户session_id下session数据中。这个token码就在表单的隐藏域中。在用户提交该表单的时候会跟随其他数据一并提交。后台会进行数据验证,包括什么用户名验证(不为空,不能包含中文等),密码验证(不能全为数字,不能少于10位等),还有其他乱其八糟的验证。其中就包括token验证(与该用户session_id下储存的token码进行比对),如果token为空或者不等于当前session中存储的token码,就说明该表单为外部提交表单或者是重复提交表单,将不在进行数据库操作。如果token和其他数据都验证通过了,(先把session中的token码清空)进行数据库操作,提交数据。

注意:不论token码验证失败还是成功,都必须进行清空。如果验证失败了没有清空session中的token,如果你的验证规则不好(token不唯一),可能多试几次就会通过了。如果验证成功了,页面没有进行跳转,你也没清空session中的token,多点几次提交,这些数据也都会提交。

二实例

这里我那TP5框架里的表单验证来举例。
商品分类表单提交页面:

表单后台代码(只贴一部分):

<div class="ncap-form-default">        <div class="bot">            <input type="hidden" name="id" value="{$Info.id}"><input type="hidden" name="__token__" value="{$Request.token}" /><a href="JavaScript:void(0);" class="ncap-btn-big ncap-btn-green" onClick="ajax_submit_form('addEditCoordinatesForm','{:U('Coordinates/addEditCoordinates?is_ajax=1')}');">确认提交</a></div></div> </form>

后台代码:

if((I('is_ajax')==1) && IS_POST){$data = I('post.');$validate = \think\Loader::validate('Goods');if (!$validate->batch()->check($data)) {//数据验证$error = $validate->getError();$error_msg = array_values($error);$return_arr = array('status' => -1,'msg' => $error_msg[0],'data' => $error,);$this->ajaxReturn($return_arr);}

这段代码是后台调取验证规则的,以下是我的验证规则:

<?php
namespace app\admin\validate;
use think\Validate;
class Goods extends Validate
{// 验证规则protected $rule = [['Goods_name','require|unique:goods','商品名称必填|商品名称重复'],['Goods_sn', 'unique:goods', '商品货号重复'], // 更多 内置规则 http://www.kancloud.cn/manual/thinkphp5/129356['shop_price','regex:\d{1,10}(\.\d{1,2})?$','本店售价格式不对。'],['market_price','regex:\d{1,10}(\.\d{1,2})?$','市场价格式不对。'],['weight','regex:\d{1,10}(\.\d{1,2})?$','重量格式不对。'],['exchange_integral','checkExchangeIntegral','积分抵扣金额不能超过商品总额'],['__token__','token','正在拼了死命的加载中······'],];

验证规则数组中的一个值是要验证的字段,第二个值时要调用的规则(可以自定义规则),第三个是提示信息。TP5的官方手册的写法让人困惑感觉好像是token验证是追加到了某个字段(如name字段)的后边,好像必须要依附于某个字段才能进行验证。

先不提官方文档。我这样写是标准格式,绝对没有问题的。

注意:这里需要注意一个细节,观察token源码,发现生成token是在Request类里:

/*** 生成请求令牌* @access public* @param string $name 令牌名称* @param mixed  $type 令牌生成方法* @return string*/public function token($name = '__token__', $type = 'md5'){$type  = is_callable($type) ? $type : 'md5';$token = call_user_func($type, $_SERVER['REQUEST_TIME_FLOAT']);if ($this->isAjax()) {header($name . ': ' . $token);}Session::set($name, $token);return $token;}

然后验证token是在Validate类里:

/*** 验证表单令牌* @access protected* @param mixed     $value  字段值* @param mixed     $rule  验证规则* @param array     $data  数据* @return bool*/protected function token($value, $rule, $data){$rule = !empty($rule) ? $rule : '__token__';if (!isset($data[$rule]) || !Session::has($rule)) {// 令牌数据无效return false;}// 令牌验证if (isset($data[$rule]) && Session::get($rule) === $data[$rule]) {// 防止重复提交Session::delete($rule); // 验证完成销毁sessionreturn true;}// 开启TOKEN重置Session::delete($rule);return false;}

而每次验证完token,都会进行清空,所以所有的其他验证规则到要放到token验证之前,不然token验证完成了,而其他有的字段验证未通过,你的表单是需要重新填写的,否则会永远提交不上。放到最后边,即使其他字段验证失败,从新修改那个字段继续提交即可,不需要重新填写表单。哒哒······结束啦。

PHP表单TOKEN防止重复提交相关推荐

  1. python表单防重复提交_传统方式提交表单,防止重复提交问题?

    提交表单的时候,不是使用ajax提交,就是传统的表单提交,为防止表单重复提交,应该怎么写javascript或jquery代码呢?如果提交没成功,怎么恢复提交按钮? html如下: Email add ...

  2. php表单页面防重复提交方法总结

    用户提交表单时可能因为网速的原因,或者网页被恶意刷新,致使同一条记录重复插入到数据库中,这是一个比较棘手的问题.我们可以从客户端和服务器端一起着手,设法避免同一表单的重复提交. 1.使用客户端脚本 提 ...

  3. 表单防止页面重复提交方法

    用户在操作表单数据时往往会出现表单数据重复提交的问题,尤其实在Web开发中此类问题比较常见.刷新页面,后退操作以前的页面,单机多次按钮都会导致数据重复提交.此类问题是因为浏览器重复提交HTTP请求导致 ...

  4. python测试开发django-162.ajax 提交表单,防重复提交(beforeSend)

    前言 form 表单提交的时候,当快速点击提交按钮的时候,会触发多个请求过去,会导致重复添加. 前端页面 前端form表单页面,2个输入框,一个提交按钮 <form id="form& ...

  5. 表单 multipart/form-data 如何提交中文乱码

    表单 multipart/form-data 如何提交中文乱码 解决方案: multipart/form-data 是用来上传文件时的一个类型 如果用这个的话,有一个专门的乱码解决的啊**.getSt ...

  6. MVC中一个表单实现多个提交按钮(一个action搞定添删改)

    默认情况下,一个表单只能有一个提交事件,这不难理解,但有时我们需要有多个实现,早在ASP时代就可以实现这个功能,难道到了MVC时代后,功能削减了?当然不是,这和MVC本身有关,微软在这方面比较提倡一个 ...

  7. JavaScript实现表单的分向提交

    在一般情况下,同一个表单只能被提交给同一个地址.但在实际web应用中,我们希望同一个表单可以根据用户的选择来完成不同的操作,即表单的分向提交. 比如说:在一个网站后台用户管理系统中,我需要对一些恶意的 ...

  8. php mysql刷新表格_php读入mysql数据并以表格形式显示(表单实现无刷新提交)

    在网上参考了些例子,于是我这个sample实现了如标题上的功能.话不多说,上代码: lishi.html 搜索 form#form1 { height: 93%; } p { width: 99%; ...

  9. Php获取id并提交表单,提交表单后 PHP获取提交内容的实现方法

    提交表单后 PHP获取提交内容的实现方法2020-06-14 15:35:24 问题:网页上提交表单之后,PHP为什么不能获取提交的内容?然而在老版本的PHP上运行却正常. 新版的PHP已经废弃了原来 ...

最新文章

  1. Ansible批量添加远程登录用户
  2. 计算机技术是双证,计算机技术在职研究生单证可以转双证吗
  3. php mysql注册登录界面_php实现登录注册界面
  4. html table设置行高_字号与行高
  5. 【转】Apache Solr 访问权限控制
  6. asp.net 发送邮件函数两则
  7. 伴鱼DQC数据质量平台实践
  8. 工资软件测试白盒测试报告,白盒测试测试报告模板.doc
  9. [渝粤教育] 南京森林警察学院 森林植物识别技术 ——珍稀植物识别 参考 资料
  10. 128g固态加1linux分区,应该如何使用128G加1T机械硬盘?要不要分盘?
  11. 判断OS版本的几个方法
  12. [Style Transfer]—Combining Markov Random Fields and Convolutional Neural Network for Image Synthesis
  13. 如何在 JavaScript 中使用对象解构
  14. 20170425めも
  15. SQL注入-安全狗apache绕过
  16. CVE-2021-3560-POLKIT本地提权漏洞复现
  17. 表格一分为二html,jsp中,td单元格怎么斜着一分为二
  18. Linux:cutycapt html转jpg、png、pdf
  19. Lightingroom4_秋凉教程P31-P76笔记
  20. 健身管理系统 健身房管理系统集成方案

热门文章

  1. TestNG教程四TestNG用例失败重试
  2. 【文本分类】常见文本分类深度学习模型汇总
  3. 加拿大约克大学计算机本科学费,2021年加拿大约克大学本科留学需要多少学费...
  4. html 图片翻页相册代码,html网页滚动相册代码
  5. 汽车行业标准程序西门子1500大型程序发那科机器人焊装CCD 扫描MES通讯RFID读写
  6. 学习笔记(01):华为工程师,带你实战C++视频精讲-Day1王桂林老师原创视频-C到C++类型安全增强...
  7. Python爬虫框架scrapy的用途及组件认识
  8. yolov5的backbone学习
  9. linux 不装显卡驱动 3d性能,Nouveau Gallium3D开源驱动N卡性能测试
  10. MySQL删除或清空表内数据的方法