深入分析php表单加入Token防止重复提交的例子
发布:smiling 来源: PHP粉丝网 添加日期:2018-05-31 10:25:58 浏览: 评论:0
Token浅谈:Token,就是令牌,最大的特点就是随机性,不可预测。一般黑客或软件无法猜测出来。
那么,Token有什么作用?又是什么原理呢?
Token一般用在两个地方——防止表单重复提交、anti csrf攻击(跨站点请求伪造)。
两者在原理上都是通过session token来实现的。当客户端请求页面时,服务器会生成一个随机数Token,并且将Token放置到session当中,然后将Token发给客户端(一般通过构造hidden表单)。下次客户端提交请求时,Token会随着表单一起提交到服务器端。
然后,如果应用于“anti csrf攻击”,则服务器端会对Token值进行验证,判断是否和session中的Token值相等,若相等,则可以证明请求有效,不是伪造的。
不过,如果应用于“防止表单重复提交”,服务器端第一次验证相同过后,会将涩session中的Token值更新下,若用户重复提交,第二次的验证判断将失败,因为用户提交的表单中的Token没变,但服务器端session中Token已经改变了。
上面的session应用相对安全,但也叫繁琐,同时当多页面多请求时,必须采用多Token同时生成的方法,这样占用更多资源,执行效率会降低。因此,也可用cookie存储验证信息的方法来代替session Token。比如,应对“重复提交”时,当第一次提交后便把已经提交的信息写到cookie中,当第二次提交时,由于cookie已经有提交记录,因此第二次提交会失败。
不过,cookie存储有个致命弱点,如果cookie被劫持(xss攻击很容易得到用户cookie),那么又一次gameover。黑客将直接实现csrf攻击。
深入分析php表单加入Token防止重复提交的例子,所以,安全和高效相对的。具体问题具体对待吧。
php表单加入Token防止重复提交:原理在于生成一个随机字符串放在session里,提交表单后来验证这个字符串,可以做到防止他人自己写form来欺骗提交,重复提交或者双击提交。
深入分析php表单加入Token防止重复提交的例子,简单的用php实现的代码如下:
- <?php
- /*
- * PHP简单利用token防止表单重复提交
- * 此处理方法纯粹是为了给初学者参考
- */
- session_start();
- function set_token() {
- $_SESSION['token'] = md5(microtime(true));
- }
- function valid_token() {
- $return = $_REQUEST['token'] === $_SESSION['token'] ? true : false;
- set_token();
- return $return;
- }
- //如果token为空则生成一个token
- if(!isset($_SESSION['token']) || $_SESSION['token']=='') {
- set_token();
- }
- if(isset($_POST['test'])){
- if(!valid_token()){
- echo "token error";
- }else{
- echo '成功提交,Value:'.$_POST['test'];
- } //phpfensi.com
- }
- ?>
- <form method="post" action="">
- <input type="hidden" name="token" value="<?php echo $_SESSION['token']?>">
- <input type="text" name="test" value="Default">
- <input type="submit" value="提交" />
- </form>
上面的比较简单一点的方法,下面的代码更加安全一点。
Token.php
- <?php
- /*
- * Created on 2013-3-25
- *
- * To change the template for this generated file go to
- * Window - Preferences - PHPeclipse - PHP - Code Templates
- */
- function getToken($len = 32, $md5 = true) {
- # Seed random number generator
- # Only needed for PHP versions prior to 4.2
- mt_srand((double) microtime() * 1000000);
- # Array of characters, adjust as desired
- $chars = array (
- 'Q',
- '@',
- '8',
- 'y',
- '%',
- '^',
- '5',
- 'Z',
- '(',
- 'G',
- '_',
- 'O',
- '`',
- 'S',
- '-',
- 'N',
- '<',
- 'D',
- '{',
- '}',
- '[',
- ']',
- 'h',
- ';',
- 'W',
- '.',
- '/',
- '|',
- ':',
- '1',
- 'E',
- 'L',
- '4',
- '&',
- '6',
- '7',
- '#',
- '9',
- 'a',
- 'A',
- 'b',
- 'B',
- '~',
- 'C',
- 'd',
- '>',
- 'e',
- '2',
- 'f',
- 'P',
- 'g',
- ')',
- '?',
- 'H',
- 'i',
- 'X',
- 'U',
- 'J',
- 'k',
- 'r',
- 'l',
- '3',
- 't',
- 'M',
- 'n',
- '=',
- 'o',
- '+',
- 'p',
- 'F',
- 'q',
- '!',
- 'K',
- 'R',
- 's',
- 'c',
- 'm',
- 'T',
- 'v',
- 'j',
- 'u',
- 'V',
- 'w',
- ',',
- 'x',
- 'I',
- '$',
- 'Y',
- 'z',
- '*'
- );
- # Array indice friendly number of chars;
- $numChars = count($chars) - 1;
- $token = '';
- # Create random token at the specified length
- for ($i = 0; $i < $len; $i++)
- $token .= $chars[mt_rand(0, $numChars)];
- # Should token be run through md5?
- if ($md5) {
- # Number of 32 char chunks
- $chunks = ceil(strlen($token) / 32);
- $md5token = '';
- # Run each chunk through md5
- for ($i = 1; $i <= $chunks; $i++)
- $md5token .= md5(substr($token, $i * 32 - 32, 32));
- # Trim the token
- $token = substr($md5token, 0, $len);
- }
- return $token;
- }
- ?>
form.php
- <?php
- include_once("token.php");
- $token = getToken();
- session_start();
- $_SESSION['token'] = $token;
- ?>
- <form action="action.php" method="post"
- <input type="hidden" name="token" value="<?=$token?>" />
- <!-- 其他input submit之类的 -->
- </form>
action.php
- <?php
- session_start();
- if($_POST['token'] == $_SESSION['token']){
- unset($_SESSION['token']);
- echo "这是一个正常的提交请求";
- }else{
- echo "这是一个非法的提交请求";
- }
- ?>
Tags: 表单 例子 Token
相关文章
- ·利用Php的CURL POST提交表单登录实例详解(2014-07-08)
- ·php 表单令牌防止重复提交原理(2014-08-21)
- ·php 解决表单重复提交实现方法介绍(2014-08-27)
- ·PHP提交表单失败后如何保留填写的信息(2014-08-27)
- ·详解Yii2定制表单输入字段的标签和样式的方法(2018-09-25)
- ·php避免form表单重复提交(2018-10-16)
- ·PHP实现表单提交时去除斜杠的教程(2018-10-26)
- ·php ci 获取表单中多个同名input元素值的代码(2021-07-21)
- ·php 提交表单 关闭layer弹窗iframe的实例讲解(2021-10-25)
- ·PHP实现一个双向队列例子(2014-06-08)
- ·php Flyweight享元模式使用例子(2014-06-10)
- ·php多进程几个例子(2014-06-17)
- ·php计划任务的实现例子介绍(2014-06-18)
- ·PHPMailer实现邮件发送例子(2014-06-20)
- ·PHP中Soap模块安装与使用例子(2014-06-20)
- ·php中Curl函数常用的两个例子,登陆/soap(2014-08-27)
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)