php通行证设计,分析pw的通行证原理

该博客探讨了一个通行证系统的实现,涉及服务器端与客户端之间的数据交换。代码中包含了登录和注销的功能,通过加密和验证机制确保数据安全。在用户登录时,服务器会将用户信息加密并发送给客户端,客户端验证后更新或创建用户数据。博客还提到了VeryCMS的一个特殊接口,并讨论了可能存在的安全隐患和不稳定性。
摘要由CSDN通过智能技术生成

其实这个很早以前也研究过

但是由于没有记录下

时间一长了就忘记了

实现程序主要有:require/passport_server.php,passport_client.php

每次登录或注册时,服务端都会包含require/passport_server.php

来看看passport_server.php里面有什么东西

!function_exists('readover') && exit('Forbidden');

if(!$passport_ifopen || $passport_type != 'server'){

Showmsg('passport_close');

}

!$forward && $forward = $db_cmsurl;

$clienturl=explode("\n",str_replace("\r","",$passport_urls));

//题外话,这段代码我看不出有什么特别,只觉得好像一无用处

//因为passort_urls就是在设置服务器端的如果我有好几个,

//他也只是取第一个不是空的就可以了。这样的话,完全是没有作用,

//还不如直接定义一个客户端地址

$jumpurl='';

while(!$jumpurl){

$jumpurl=array_shift($clienturl);

}

if(!$jumpurl){

Showmsg('undefined_action');

}

$userdb = array();

foreach($clienturl as $key=>$val){

if($val && $val != $jumpurl){

$userdb['url'] .= $userdb['url'] ? ",$val" : $val;

}

}

$rt=$db->get_one("SELECT uid,username,password,email,rvrc,money,credit FROM pw_user WHERE uid='$winduid'");

//这里就是接口所用到的其中一个重要数据

//有占类似支付宝的接口

//但显然是后其更改进的

//看下面的注释

$userdb['uid']    = $rt['uid'];

$userdb['username']  = $rt['username'];

$userdb['password']  = $rt['password'];

$userdb['email']  = $rt['email'];

$userdb['rvrc']    = $rt['rvrc'];

$userdb['money']  = $rt['money'];

$userdb['credit']  = $rt['credit'];

$userdb['time']    = $timestamp;

$userdb['cktime']  = $cktime;

//看这里是将数据转成字符串

$userdb_encode='';

foreach($userdb as $key=>$val){

$userdb_encode .= $userdb_encode ? "&$key=$val" : "$key=$val";

}

//这里就是跟支付宝不同的地方,支付宝在这里是公开的。而这里使用了StrCode加密。

//相对来说是比支付宝要安全很多。但也可能出现错误,因为strcode可能会出显“=”号

//现在直接用str_replace换掉“=”号,这种做法不可取。因为这样做为程序造成一个不稳定因素

//这应该是lyn经常会说pw灵义事件之一了

//其实这个str_replace 是完全没有必要的。因为下面使用了rawurlencode

$db_hash=$passport_key;

$userdb_encode=str_replace('=','',StrCode($userdb_encode));

if($action=='login'){

//verify,就是跟支付宝差不多的东西。确保数据没有变更改过。

$verify = md5("login$userdb_encode$forward$passport_key");

//主要提供三个变量到客户端去就可以完成服务端的工作了。

ObHeader("$jumpurl/passport_client.php?action=login&userdb=".rawurlencode($userdb_encode)."&forward=".rawurlencode($forward)."&verify=".rawurlencode($verify));

}elseif($action=='quit'){

$verify = md5("quit$userdb_encode$forward$passport_key");

ObHeader("$jumpurl/passport_client.php?action=quit&userdb=".rawurlencode($userdb_encode)."&forward=".rawurlencode($forward)."&verify=".rawurlencode($verify));

}

?>

当客户端接收到服务器提交的三个变量后

require_once('global.php');

require_once(R_P.'mod/checkpass_mod.php');

if(!$passport_ifopen || $passport_type != 'client'){

exit("Passport closed(VeryCMS)");

}

if(md5($action.$userdb.$forward.$passport_key) != $verify){

exit('Illegal request(VeryCMS)');

}

$_db_hash=$db_hash;

//还原用户数据

$db_hash=$passport_key;

parse_str(StrCode($userdb,'DECODE'),$userdb);

if($action=='login'){

foreach($userdb as $key=>$val){

$userdb[$key] = addslashes($val);

}

if(!$userdb['time'] || !$userdb['username'] || !$userdb['password'] || !$userdb['email']){

exit("Lack of parameters(VeryCMS)");

}

if($timestamp-$userdb['time']>3600){

exit('Passport request expired(VeryCMS)');

}

//题外话:这里里verycms的一段特殊接口,不知道为什么会另外写一般关于verycms的接口,而不是使用一个统一的接口,

//如果以后还其它的程序是不是还要另外加一段程序?

//verycms passport group right

$groupright=1;

include_once(D_P.'data/cache/passport.php');

if($ps_combine){

$db->select_db($ps_bbsdbname);

$PW = $ps_bbspre;

$gp = $db->get_one("SELECT hk_value FROM pw_hack WHERE hk_name='bg_groups'");

$rt = $db->get_one("SELECT groupid,memberid FROM pw_members WHERE uid='$userdb[uid]'");

Add_S($rt);

Add_S($gp);

$groupid = $rt['groupid'] == '-1' ? $rt['memberid'] : $rt['groupid'];

if($gp['hk_value'] && strpos($gp['hk_value'],",$groupid,")===false){

$groupright=0;

$forward .= "/?nogroupright";

}

include (D_P.'data/sql_config.php');

$db->select_db($dbname);

}

//verycms passport group right

if($groupright){

$user_field = array('username','password','email');

$credit_field = array('rvrc','money','credit');

$sql='';

foreach($user_field as $key=>$val){

$sql .= ','.$val;

}

foreach($credit_field as $key=>$val){

$sql .= ','.$val;

}

//先看查是否有这个用户,使用的是用户名作关联,这个方案是不错,毕竟不是所有论坛程序都会有uid,

//pw的另一套程序ofstar

$rt=$db->get_one("SELECT uid $sql FROM pw_user WHERE username='$userdb[username]'");

if($rt){

$sql='';

foreach($userdb as $key=>$val){

if($rt[$key] != $val){

if(in_array($key,$user_field)){

$sql  .= $sql ? ",$key='$val'" : "$key='$val'";

}elseif(in_array($key,$credit_field) && strpos(",$passport_credit,",",$key,")!==false){

$sql .= $sql ? ",$key='$val'" : "$key='$val'";

}

}

}

if($sql){

$db->update("UPDATE pw_user SET $sql WHERE uid='$rt[uid]'");

$db->update("UPDATE pw_domain SET bbsuid='$userdb[uid]',username='$userdb[username]' WHERE uid='$rt[uid]'");

}

$winduid = $rt['uid'];

}else{

$sql1=$sql2='';

foreach($userdb as $key=>$val){

if(in_array($key,$user_field)){

$sql1 .= $sql1 ? ','.$key  : $key;

$sql2 .= $sql2 ? ",'$val'" : "'$val'";

}elseif(in_array($key,$credit_field) && strpos(",$passport_credit,",",$key,")!==false){

$sql1 .= $sql1 ? ','.$key  : $key;

$sql2 .= $sql2 ? ",'$val'" : "'$val'";

}

}

//刚开始我在想,论坛的用户是怎么在blog里直接建一个帐呢?原来就是用Replace关键字来建的。

//下面三个$db->update都是会对数据作出更改或添加。可是我很奇怪。

//为什么在register.php文件里会对以下的数据进行过滤,而在这里却一点都不过滤就直接使用呢?

//是不是很相信,使用pwblog程序的人只会使用pwfourm呢?

//但就算都是用pwfourm,那用户使用中文呢?

//有点不负责任的感觉。

$db->update("REPLACE INTO pw_user($sql1,groupid,memberid,gender,regdate,signchange) VALUES($sql2,'-1','8','0','$timestamp','1')");

$winduid = $db->insert_id();

//

$db->update("REPLACE INTO pw_domain(uid,bbsuid,username,blogname) VALUES ('$winduid','$userdb[uid]','$userdb[username]','$userdb[username]')");

$db->update("UPDATE pw_bloginfo SET newmember='$userdb[username]',totalmember=totalmember+1 WHERE id='1'");

}

$db_hash=$_db_hash;

$windpwd = confuse($userdb['password']);

Cookie("bloguser",StrCode($winduid."\t".$windpwd),$userdb['cktime']);

Cookie('lastvisit','',0);

Loginipwrite();

if($userdb['url']){

$clienturl = explode(',',$userdb['url']);

$jumpurl='';

while(!$jumpurl){

$jumpurl=array_shift($clienturl);

}

$userdb['url'] = implode(',',$clienturl);

}

}

if($jumpurl){

$userdb_encode='';

foreach($userdb as $key=>$val){

$userdb_encode .= $userdb_encode ? "&$key=$val" : "$key=$val";

}

$db_hash=$passport_key;

$userdb_encode=str_replace('=','',StrCode($userdb_encode));

$verify = md5("login$userdb_encode$forward$passport_key");

ObHeader("$jumpurl/passport_client.php?action=login&userdb=".rawurlencode($userdb_encode)."&forward=".rawurlencode($forward)."&verify=".rawurlencode($verify));

}else{

ObHeader($forward ? $forward : $passport_serverurl);

}

}elseif($action=='quit'){

$db_hash=$_db_hash;

Loginout();

if($userdb['url']){

$clienturl = explode(',',$userdb['url']);

$jumpurl='';

while(!$jumpurl){

$jumpurl=array_shift($clienturl);

}

$userdb['url'] = implode(',',$clienturl);

}

if($jumpurl){

$userdb_encode='';

foreach($userdb as $key=>$val){

$userdb_encode .= $userdb_encode ? "&$key=$val" : "$key=$val";

}

$db_hash=$passport_key;

$userdb_encode=str_replace('=','',StrCode($userdb_encode));

$verify = md5("quit$userdb_encode$forward$passport_key");

ObHeader("$jumpurl/passport_client.php?action=quit&userdb=".rawurlencode($userdb_encode)."&forward=".rawurlencode($forward)."&verify=".rawurlencode($verify));

}else{

ObHeader($forward ? $forward : $passport_serverurl);

}

}

function Loginipwrite($winduid){

global $db,$timestamp,$onlineip;

$logininfo="$onlineip|$timestamp|6";

$db->update("UPDATE pw_user SET lastvisit=thisvisit,thisvisit='$timestamp',onlineip='$logininfo' WHERE uid='$winduid'");

}

?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值