1、目的:每次表单POST提交(ajax的POST也适用)过来数据,都必须校验formhash参数是否和服务器端的一致,不一致说明重复提交或者 跨站攻击提交csrf

2、原理:参照了 KPPW 的formhash生成和校验示例。将formhash的生成写入基类构造函数,每次登陆用户操作数据,都生成hash并进行比较。

(用户未登录状态,也可以校验formhash,可以让你的网站免于 遭受  无状态脚本提交数据 攻击)

3、formHash的生成代码:注意 这里的formhash一般都是每个用户均不相同,且每个用户的formhash值在几个月以内都是不会变更的。

<?php
/*
* 再次封装的BaseController基类 --by xzz 2018/02/07
* 包括:表单formhash校验原理如下:
* 将formhash放在构造函数里,GET访问页面生成formhash并渲染在页面,用户提交表单,POST经过构造函数再一次生成一样的formhash
*/
namespace Admin\Controller;
user Think\Controller;
class BaseController extends Controller {
public function __construct(){
parent::__construct();
define("FORMHASH", self::formhash());
@session_start();
}
/* 生成表单随机码,防止XSS攻击,无需同步存储于内存缓存(redis/Mencached)中
* 返回6位随机码
*/
static function formhash() {
$uid = null;
$username = null;
if (isset ( $_SESSION ['uid'] )) {
$uid = $_SESSION ['uid'];
}
if (isset ( $_SESSION ['username'] )) {
$username = $_SESSION ['username'];
}
return substr ( md5 ( substr ( time (), 0, - 7 ) . $uid . $username ), - 6 );
}
/*
* formhash校验,传过来的formhash和提交动作再次生成的FORMHASH变量一致,校验通过;否则重复提交
*/
static function submitcheck($formhash, $return_json = false) {if (! empty ( $formhash ) && $_SERVER ['REQUEST_METHOD'] == 'POST') {
if ((empty ( $_SERVER ['HTTP_REFERER'] ) || preg_replace ( "/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER ['HTTP_REFERER'] ) == preg_replace ( "/([^\:]+).*/", "\\1", $_SERVER ['HTTP_HOST'] )) && $formhash == FORMHASH) {
return true;
} elseif ($return_json == true) {
return false;
}
} else {
return false;
}
}
/* 发送邮件类 -xzz 2018/02/06 */
public function add2(){
    //校验用户是否登录
    // do user is login ?
header("content-type:text/html;charset=utf-8");
if(IS_POST){
var_dump($_POST);
if(self::submitcheck(trim($_POST['formhash']))){
if(SendMail($_POST['mail'],$_POST['title'],$_POST['content']))
$this->success('发送成功!');
else
$this->error('发送失败');
}else{
exit("formhash错误");
}
}elseif(IS_GET){
$this->assign("FORMHASH",FORMHASH);$this->display();
}
} }

4、代码解读:

a. 假设 我们访问上面 add2 页面,首先 输出变量$FORMHASH 并展示在页面隐藏域;

b. post方式提交后,校验登录态->校验formhash->do what u want to do ..

c. 第二步,校验formhash:提交的formhash 和 再次生成formhash比较,还看不懂 请再尝试看5遍这个方法 【submitcheck()】

5、结束。

【PHP】(原创)之表单FORM的formhash校验,以TP3.2示例的更多相关文章

  1. HTML ------ 关于表单 Form

    Form(表单)主要用于采集和提交用户输入的信息,是页面与WEB服务器交互过程中 最重要的信息来源. 掌握表单(Form)有以下几个要点: 重要form属性 form常用控件 form提交方式 § 重 ...

  2. Bootstrap~表单Form

    回到目录 在进行自己的后台改版时,大体布局都使用了bootstrap,剩下的表单部分没理由不去使用它,对于表单的美化和布局,bootstrap做的也是很不错的,有大气的边框,多功能的按钮及宏观的表单布 ...

  3. 表单 - Form - EasyUI提供的表单异步提交

    方案一 被提交的表单 <form id="loginForm" method="post"> <table align="cente ...

  4. 跟服务器交互的Web表单(form)

    使用HTML来构建可以跟服务器交互的Web表单(form),通过给你的form元素添加一个action属性来达到此目的. action属性的值指定了表单提交到服务器的地址. 例如: <form ...

  5. 3、网页制作Dreamweaver(表单form)

    表单form (虚线不显示) 1.写法: <form id="form1" name="form1" method="post" ac ...

  6. DHTMLX 前端框架 建立你的一个应用程序 教程(九)--绑定表单Form到表格Grrid中

    绑定表单Form到表格Grrid中 现在我们需要选中一行表格数据的时候 数据能在表单中显示出来 我们可以使用DHTMLX 丰富的组件功能实现它. 绑定表单到表格 1.调用bind方法将表单绑定到网格, ...

  7. DHTMLX 前端框架 建立你的一个应用程序 教程(八)-- 添加表单Form

    添加表单Form 我们下一步是在页面中添加一个表单,表格中的选中字段将会显示在表单中.提供一个提交按钮 可以对显示的数据进行修改提交. 添加表单到布局单元格中 1.在右侧布局中使用attachForm ...

  8. 微信小程序基础之表单Form的使用

    表单Form的应用很广泛,我们可以利用form设计登录注册,也可以设计一种答题问卷的形式,今天主要讲一下form的使用 form表单,将组件内输入的"switch","i ...

  9. HTML(七)HTML 表单(form元素介绍,input元素的常用type类型,input元素的常用属性)

    前言 表单是网页与用户的交互工具,由一个<form>元素作为容器构成,封装其他任何数量的表单控件,还有其他任何<body>元素里可用的标签 表单能够包含<input> ...

随机推荐

  1. 【模拟+递归+位运算】POJ1753-Flip Game

    由于数据规模不大,利用爆搜即可.第一次用位运算写的,但是转念一想应该用递归更加快,因为位运算没有剪枝啊(qДq ) [思路] 位运算:时间效率较低(172MS),有些辜负了位运算的初衷.首先将二维数组 ...

  2. LeetCode 771. 宝石与石头(java)

    给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J 中的字母不重复,J 和 S中的所有字符都是字母 ...

  3. CDOJ 1279 班委选举 每周一题 div2 暴力

    班委选举 题目连接: http://acm.uestc.edu.cn/#/status/list?problemId=1279 Description 高考的脚步越来越近了--时间如山涧小溪一般悄无声 ...

  4. GIT使用(自用)

    1.远程分支就是本地分支push到服务器上的时候产生的.比如master就是一个最典型的远程分支(默认). 1 $: git push origin master 除了master之外,我们还可以随便 ...

  5. hdu1428漫步校园

    #include <queue> #include <iostream> #include <algorithm> #include <cstring> ...

  6. 谈谈 CSS 关键字 initial、inherit 和 unset

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  7. Linux下启动和停止Java应用程序的Shell脚本

    转自:http://blog.csdn.net/jadyer/article/details/7960802 资料参考来源自兔大侠,并略作修改:http://www.tudaxia.com/archi ...

  8. Unity3D 手游开发中所有特殊的文件夹

    这里列举出手游开发中用到了所有特殊文件夹. 1.Editor Editor文件夹可以在根目录下,也可以在子目录里,只要名子叫Editor就可以.比如目录:/xxx/xxx/Editor  和 /Edi ...

  9. The file “Info.plist” couldn’t be opened because there is no such file

    修改了Info.plist的实际文件位置(项目和单元测试对应不同的Info.plist),报错 (null): could not read data from '/Users/xxxxx/Deskt ...

  10. Unity-EasyTouch插件之Two Finger

    今天,我们来学习下多手指触摸屏幕的事件,分别有挤压(缩放),挤压(旋转) 挤压(缩放): 在easytouch中,双手指挤压缩放的英文为Pinch 好了今天我们的测试是双手指挤压对物体进行缩放.我们测 ...