PHP令牌 Token改进版


Posted in PHP onJuly 18, 2008

正是由于使用了 base64 ,所以在把这个令牌通过 GET方法发送的时候,出现了问题。
比如:http://test/test.php?a=1+2
你用 $_GET["a"] 取得是:1 2 ,即那个加号没有了。一开始我用 urlencode 对其进行转换,但是总有那么一两的结果是意料外的。

后来想想 base64 的字符就限定于: [A-Za-z0-9\+\/=] 这么多,加号出问题,我就把加号换成不出问题的符号,下划线是最好的选择。下面是修改后的代码:

GEncrypt.inc.php

<?php  
class GEncrypt {  
 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 ( (( 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 ( preg_replace("/\\+/s","_", base64_encode ( self::keyED ( $tmp, $key ) ) ));  
 }  
 //base64 [A-Za-z0-9\+\/=]  
 public static function decrypt($txt, $key) {  
  if($txt == ""){ return false;}   
  //echo preg_replace("/_/s","+",$txt);  
  $txt = self::keyED (base64_decode ( preg_replace("/_/s","+", $txt) ), $key );  
  $tmp = "";  
  for($i = 0; $i < strlen ( $txt ); $i ++) {  
   $md5 = substr ( $txt, $i, 1 );  
   $i ++;  
   $tmp .= (substr ( $txt, $i, 1 ) ^ $md5);  
  }  
  return $tmp;  
 }  
}  
?> 

GToken.inc.php
<?php  
/**  
 * 原理:请求分配token的时候,想办法分配一个唯一的token, base64( time + rand + action)  
 * 如果提交,将这个token记录,说明这个token以经使用,可以跟据它来避免重复提交。  
 *  
 */  
class GToken {   /**  
  * 得到当前所有的token  
  *  
  * @return array  
  */  
 public static function getTokens(){  
  $tokens = $_SESSION[GConfig::SSN_KEY_TOKEN ];  
  if (empty($tokens) && !is_array($tokens)) {  
   $tokens = array();  
  }  
  return $tokens;  
 }  
 /**  
  * 产生一个新的Token  
  *  
  * @param string $formName  
  * @param 加密密钥 $key  
  * @return string  
  */  
 public static function newToken($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){  
  if(empty($token)) return false;  
  $tokens = self::getTokens();  
  if (in_array($token,$tokens)) //如果存在,说明是以使用过的token  
   return false;  
  $source = GEncrypt::decrypt($token,$key);  
  if($fromCheck)  
   return $source == $formName.session_id();  
  else{  
   return strpos($source,$formName) === 0;  
  }  
 }  
 public static function getTokenKey($token,$key = GConfig::ENCRYPT_KEY){  
  if($token == null || trim($token) == "") return false;  
  $source = GEncrypt::decrypt($token,$key);  
  return $source != "" ? str_replace(session_id(),"",$source) : false;  
 }  
 public function newTokenForSmarty($params){  
  $form = null;  
  extract($params);  
  return self::newToken($form);  
 }  
}  
?> 
PHP 相关文章推荐
初学者入门:细述PHP4的核心Zend
Sep 05 PHP
通过html表格发电子邮件
Oct 09 PHP
如何将数据从文本导入到mysql
Oct 09 PHP
重新封装zend_soap实现http连接安全认证的php代码
Jan 12 PHP
jQuery 源码分析笔记
May 25 PHP
基于php中使用excel的简单介绍
Aug 02 PHP
教你如何使用php session
Oct 28 PHP
php实现将Session写入数据库
Jul 26 PHP
作为程序员必知的16个最佳PHP库
Dec 09 PHP
php微信公众平台开发之微信群发信息
Sep 13 PHP
PHP读取文本文件并逐行输出该行使用最多的字符与对应次数的方法
Nov 25 PHP
PHP实现笛卡尔积算法的实例讲解
Dec 22 PHP
php下intval()和(int)转换使用与区别
Jul 18 #PHP
PHP入门学习的几个不错的实例代码
Jul 13 #PHP
php header()函数使用说明
Jul 10 #PHP
php下实现一个阿拉伯数字转中文数字的函数
Jul 10 #PHP
兼容PHP5的PHP目录管理函数库
Jul 10 #PHP
php 防止单引号,双引号在接受页面转义
Jul 10 #PHP
功能齐全的PHP发送邮件类代码附详细说明
Jul 10 #PHP
You might like
一个比较简单的PHP 分页分组类
2009/12/10 PHP
PHP 使用redis简单示例分享
2015/03/05 PHP
php封装的smarty类完整实例
2016/10/19 PHP
PHP反射原理与用法深入分析
2019/09/28 PHP
js正确获取元素样式详解
2009/08/07 Javascript
十分钟打造AutoComplete自动完成效果代码
2009/12/26 Javascript
基于jQuery的淡入淡出可自动切换的幻灯插件打包下载
2010/09/15 Javascript
Javascript写入txt和读取txt文件示例
2014/02/12 Javascript
Jquery方式获取iframe页面中的 Dom元素
2014/05/07 Javascript
React Native实现简单的登录功能(推荐)
2016/09/19 Javascript
微信小程序之ES6与事项助手的功能实现
2016/11/30 Javascript
基于Vue实现后台系统权限控制的示例代码
2017/08/29 Javascript
Vue组件和Route的生命周期实例详解
2018/02/10 Javascript
解决在Bootstrap模糊框中使用WebUploader的问题
2018/03/22 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
Vue实现远程获取路由与页面刷新导致404错误的解决
2019/01/31 Javascript
基于vue实现滚动条滚动到指定位置对应位置数字进行tween特效
2019/04/18 Javascript
Vue axios 将传递的json数据转为form data的例子
2019/10/29 Javascript
Python模块学习 re 正则表达式
2011/05/19 Python
在Python中封装GObject模块进行图形化程序编程的教程
2015/04/14 Python
Python设计模式编程中解释器模式的简单程序示例分享
2016/03/02 Python
详解python中的time和datetime的常用方法
2019/07/08 Python
Python常用模块sys,os,time,random功能与用法实例分析
2020/01/07 Python
Windows下Sqlmap环境安装教程详解
2020/08/04 Python
Kathmandu英国网站:新西兰户外运动品牌
2017/03/27 全球购物
皮姆斯勒语言学习:Pimsleur Language Programs
2018/06/30 全球购物
Desigual美国官方网站:西班牙服装品牌
2019/03/29 全球购物
秋季运动会通讯稿
2014/01/24 职场文书
公司中秋节活动方案
2014/02/12 职场文书
书香校园活动方案
2014/02/28 职场文书
事假请假条范文
2014/04/11 职场文书
乡镇党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
导游词之南昌滕王阁
2019/11/29 职场文书
如何用python识别滑块验证码中的缺口
2021/04/01 Python
「女孩的钓鱼慢活」全新版权绘公布
2022/03/21 日漫
MySQL导致索引失效的几种情况
2022/06/25 MySQL