PHP Token(令牌)设计

转载链接:http://www.jb51.net/article/13756.htm


PHP Token(令牌)设计 设计目标: 避免重复提交数据. 检查来路,是否是外部提交 匹配要执行的动作(如果有多个逻辑在同一个页面实现,比如新增,删除,修改放到一个PHP文件里操作) 这里所说的token是在页面显示的时候,写到FORM的一个隐藏表单项(type=hidden). token不可明文,如果是明文,那就太危险了,所以要采用一定的加密方式.密文要可逆.俺算法很白痴,所以采用了网上一个现成的方法.

怎样避免重复提交?
在SESSION里要存一个数组,这个数组存放以经成功提交的token.在后台处理时,先判断这个token是否在这个数组里,如果存在,说明是重复提交. 
如何检查来路?
可选项,这个token在生成的时候,加入了当前的session_id.如果别人copy你的html(token一迸copy),在提交时,理论上token里包含的session_id不等于当前session_id,就可以判断这次提交是外部提交. 
如何匹配要执行的动作?
在token的时候,要把这个token的动作名称写进这个token里,这样,在处理的时候,把这个动作解出来进行比较就行了.

GEncrypt.inc.php:

<?php  
class GEncrypt extends GSuperclass {  protected static function keyED($txt,$encrypt_key){     $encrypt_key = md5($encrypt_key);     $ctr=0;     $tmp = "";     for ($i=0;$i<strlen($txt);$i++){     if ($ctr==strlen($encrypt_key)) $ctr=0;     $tmp.= substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1);     $ctr++;     }     return $tmp;     }  public static function encrypt($txt,$key){     //$encrypt_key = md5(rand(0,32000));  $encrypt_key = md5(((float) date("YmdHis") + rand(10000000000000000,99999999999999999)).rand(100000,999999));  $ctr=0;     $tmp = "";     for ($i=0;$i<strlen($txt);$i++){  if ($ctr==strlen($encrypt_key)) $ctr=0;     $tmp.= substr($encrypt_key,$ctr,1) . (substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1));     $ctr++;     }     return base64_encode(self::keyED($tmp,$key));  }  public static function decrypt($txt,$key){  $txt = self::keyED( base64_decode($txt),$key);     $tmp = "";  for ($i=0;$i<strlen($txt);$i++){     $md5 = substr($txt,$i,1);     $i++;     $tmp.= (substr($txt,$i,1) ^ $md5);     }  return $tmp;  }      
}  
?> 
方法:

(1)granteToken 参数:formName,即动作名称,key是加密/解密 密钥.
返回一个字符串,形式是: 加密(formName:session_id)
(2)isToken 参数:token 即granteToken产生的结果,formName,动作名称,fromCheck是否检查来路,如果为真,还要判断token里的session_id是否和当前的session_id一至.
(3)dropToken,当成功执行一个动作后,调用这个函数,把这个token记入session里,

GToken.inc.php

<?php  
/**  
* 原理:请求分配token的时候,想办法分配一个唯一的token, base64( time + rand + action)  
* 如果提交,将这个token记录,说明这个token以经使用,可以跟据它来避免重复提交。  
*  
*/  
class GToken {  /**  * 得到当前所有的token  *  * @return array  */  public static function getTokens(){  $tokens = $_SESSION[GConfig::SESSION_KEY_TOKEN ];  if (empty($tokens) && !is_array($tokens)) {  $tokens = array();  }  return $tokens;  }  /**  * 产生一个新的Token  *  * @param string $formName  * @param 加密密钥 $key  * @return string  */  public static function granteToken($formName,$key = GConfig::ENCRYPT_KEY ){  $token = GEncrypt::encrypt($formName.":".session_id(),$key);  return $token;  }  /**  * 删除token,实际是向session 的一个数组里加入一个元素,说明这个token以经使用过,以避免数据重复提交。  *  * @param string $token  */  public static function dropToken($token){  $tokens = self::getTokens();  $tokens[] = $token;  GSession::set(GConfig::SESSION_KEY_TOKEN ,$tokens);  }  /**  * 检查是否为指定的Token  *  * @param string $token    要检查的token值  * @param string $formName  * @param boolean $fromCheck 是否检查来路,如果为true,会判断token中附加的session_id是否和当前session_id一至.  * @param string $key 加密密钥  * @return boolean  */  public static function isToken($token,$formName,$fromCheck = false,$key = GConfig::ENCRYPT_KEY){  $tokens = self::getTokens();  if (in_array($token,$tokens)) //如果存在,说明是以使用过的token  return false;  $source = split(":", GEncrypt::decrypt($token,$key));  if($fromCheck)  return $source[1] == session_id() && $source[0] == $formName;  else  return $source[0] == $formName;  }  
}  
?> 

从$_POST里取出token,用isToken判断.

如果想判断是否是执行的匹配动作,可以把isToken里的formName改一下,运行,很好,没有匹配上.证明这个成功. 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java rwd_面向任务的设计-不仅限于Mobile First和RWD

java rwdWe already know that majority of solutions should start with a design for smartphones, we know that all websites should be responsive. Now, it’s time to think about holistic solutions with specific tasks adapted to all kind of devices.我们已经知道…

python中关键字 表示空类型_python中什么表示空类型

python中什么表示空类型&#xff1f;python中None表示空类型。表示该值是一个空对象&#xff0c;空值是Python里一个特殊的值&#xff0c;用None表示。None不能理解为0&#xff0c;因为0是有意义的&#xff0c;而None是一个特殊的空值。可以将None赋值给任何变量&#xff0c;也…

HOJ 1015 Nearly prime numbers

代码 //Nearly prime number is an integer positive number for which it is possible //to find such primes P1 and P2 that given number is equal to P1*P2.#include <stdio.h>#include <stdlib.h>#include <math.h>//decide n whither is a nearly pri…

「前端工程化」该怎么理解?

大家好&#xff0c;我是若川。今天分享一篇「前端工程化」的好文。非广告&#xff0c;请放心阅读。可点击下方卡片关注我&#xff0c;或者查看系列文章。今天发文比较晚&#xff0c;以往都是定时早上7:30发文&#xff0c;也不知道是不是有点早。一.什么是前端工程&#xff1f;一…

axure文本框值相加_Axure教程:计数文本域实现

原标题&#xff1a;Axure教程&#xff1a;计数文本域实现制定UI规范时&#xff0c;遇到实现“限制字数的文本域”的交互问题&#xff0c;即当用户输入的字数长度超过限制要求&#xff0c;如何只保留规定长度的文本&#xff1f;效果如下&#xff1a;我们知道【Number】类型的文本…

figma下载_Figma和ProtoPie中的原型制作,比较

figma下载第1部分 (Part 1) Prototyping has never had such a high profile with a whole host of tools that now give you varying ability to realize your designs beyond their static UI and into a working usable thing. It’s fair to say that prototyping within t…

拗口翻译

I find many times people use temporary tables because they learned in other databases that joining too many tables in a single query is a ʹbad thingʹ. This is a practice that must be unlearned for Oracle development. Rather then trying to out‐smart the …

javascript 手机手势动作touch触屏原理分析

转载链接&#xff1a;http://www.lvtao.net/web/220.html $(function(){document.getElementById("moveId").addEventListener(touchstart, touchStart);document.getElementById("moveId").addEventListener(touchmove, touchMove);document.getElementBy…

并发工具类(四)线程间的交换数据 Exchanger

前言JDK中为了处理线程之间的同步问题&#xff0c;除了提供锁机制之外&#xff0c;还提供了几个非常有用的并发工具类&#xff1a;CountDownLatch、CyclicBarrier、Semphore、Exchanger、Phaser&#xff1b;  CountDownLatch、CyclicBarrier、Semphore、Phaser 这四个工具类提…

「前端组件化」该怎么理解?

大家好&#xff0c;我是若川。今天分享一篇关于「前端组件化」的好文。欢迎点击下方卡片关注我。以下是正文~这里我们一起来学习前端组件化的知识&#xff0c;而组件化在前端架构里面是最重要的一个部分。讲到前端架构&#xff0c;其实前端架构中最热门的就有两个话题&#xff…

大屏设计的视觉统一_视觉设计中的统一

大屏设计的视觉统一视觉设计的统一性是什么&#xff1f; (What is unity in visual design?) The concept of unity in visual design means a group of elements working together to create a greater whole. It means, as the clich goes: A whole that is greater than th…

l2范数求导_机器学习中的范数规则化之(一)L0、L1与L2范数

source: https://blog.csdn.net/zouxy09/article/details/24971995zouxy09qq.comhttp://blog.csdn.net/zouxy09今天我们聊聊机器学习中出现的非常频繁的问题&#xff1a;过拟合与规则化。我们先简单的来理解下常用的L0、L1、L2和核范数规则化。最后聊下规则化项参数的选择问题。…

9.struts1.x中tiles框架的使用

在页面直接使用titles标签先引入标签&#xff1a;<%taglib uri"http://struts.apache.org/tags-tiles" prefix"tiles" %> 将模板页面要代替的内容用标签占位&#xff1a;<tiles:insert attribute"content"></tiles:insert> 在…

Debian 9.6.0 + OpenMediaVault 4.x : U盘作系统盘时遇到的问题

前几天在虚拟机试验的时候还说装到实机一般也没什么问题&#xff0c;然后突然间想试试如果把 Debian9OMV 都放到U盘里会怎么样。于是就折腾&#xff08;然后懵逼&#xff09; 先总结一下 写入openmediavault官方的iso到U盘使用UNetbootin写入Debian9的iso使用UltraISO的默认设置…

新浪微博、腾讯微博、QQ空间、人人网、豆瓣 一键分享API

转载链接&#xff1a;http://www.bluesdream.com/blog/sina-tencent-renren-douban-share-a-key-api.html 新浪微博&#xff1a; http://service.weibo.com/share/share.php?url count表示是否显示当前页面被分享数量(1显示)(可选&#xff0c;允许为空) &url将页面地址转…

跟着官方文档能学懂React Hooks就怪了

大家好&#xff0c;我是若川。今天分享一篇关于「React Hooks」的好文。欢迎点击下方卡片关注我。以下是正文~回想下你入门Hooks的过程&#xff0c;是不是经历过&#xff1a;类比ClassComponent的生命周期&#xff0c;学习Hooks的执行时机慢慢熟练以后&#xff0c;发现Hooks的执…

origin图上显示数据标签_Origin(Pro):寒假都结束了,这个图还是不会画?【数据绘图】...

寒假前给大家分享了一个图&#xff0c;大家要的教程来了。【数据绘图】好图分享&#xff1a;寒假&#xff1f;不存在的&#xff01;​mp.weixin.qq.com绘图思路&#xff1a;左侧起止时间&#xff1a;散点图&#xff0c;交换XY坐标轴&#xff1b;中间的连线为Drop Lines&#xf…

可以激发设计灵感的音乐_建立灵感库以激发您的创造力

可以激发设计灵感的音乐I often find a lot of inspiration from work I see while scrolling social media. Saving art or images that inspire you allows you to build a library of resources to draw from whenever you’re working on a project.在滚动社交媒体时&#…

CentOS服务器上部署 oracle10gr2

1、下载Centos系统 Linux 镜像文件。 推荐使用 CentOS5.4&#xff0c;下载地址&#xff1a;http://isoredirect.centos.org/centos/5/isos/i386/ 。这个是 32 位的 Linux 系统镜像安装文件&#xff0c;进入下载页面后&#xff0c;如果是 DVD 光盘安装&#xff0c;可以仅…

回顾:中网通讯网络公司CEO罗与曾作客新浪嘉宾聊天室

转载链接&#xff1a;http://tech.sina.com.cn/it/w/2001-11-09/91253.shtml 回顾&#xff1a;中网通讯网络公司CEO罗与曾作客新浪嘉宾聊天室 大家好&#xff01;   主持人 &#xff1a;各位网友&#xff0c;下午好&#xff0c;今天我们请到了中网通讯网络公司首席执行官罗…