- 论坛徽章:
- 0
|
分析pw的通行证原理
实现程序主要有:require/passport_server.php,passport_client.php
每次登录或注册时,服务端都会包含require/passport_server.php
来看看passport_server.php里面有什么东西
- <?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));
- }
- ?>
复制代码
当客户端接收到服务器提交的三个变量后
- <?php
- 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'");
- }
- ?>
复制代码
[ 本帖最后由 fan12 于 2008-9-16 02:03 编辑 ] |
|