+ -
当前位置:首页 → 问答吧 → ucenter实现跨域单点登陆的方法

ucenter实现跨域单点登陆的方法

时间:2008-08-29

来源:互联网

1.每一个应用都要包含uc_client,下面拿uchome代码举例
2.uchome登陆时访问source/do_login.php 的getpassport函数,getpassport通过uc_client 直接连ucenter的数据库,实现当前站点的登陆
3.uchome然后调用$ucsynlogin = uc_user_synlogin($setarr['uid']);实现跨域登陆
[php]
function uc_user_synlogin($uid) {
    return  uc_api_post('user', 'synlogin', array('uid'=>$uid));
}
function uc_api_post($module, $action, $arg = array()) {
$s = $sep = '';
foreach($arg as $k => $v) {
  if(is_array($v)) {
   $s2 = $sep2 = '';
   foreach($v as $k2=>$v2) {
    $s2 .= "$sep2{$k}[$k2]=".urlencode(uc_stripslashes($v2));
    $sep2 = '&';
   }
   $s .= $sep.$s2;
  } else {
   $s .= "$sep$k=".urlencode(uc_stripslashes($v));
  }
  $sep = '&';
}
$postdata = uc_api_requestdata($module, $action, $s);
return uc_fopen2(UC_API.'/index.php', 500000, $postdata, '', TRUE, UC_IP, 20);
}
function uc_api_requestdata($module, $action, $arg='', $extra='') {
$input = uc_api_input($arg);
$post = "m=$module&a=$action&inajax=2&input=$input&appid=".UC_APPID.$extra;
return $post;
}
[/php]
4.在uc_user_synlogin函数里再用uc_client/client.php的fsockopen去访问ucenter下的index.php默认超时15秒
[php]
function uc_fopen2($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) {
$__times__ = isset($_GET['__times__']) ? intval($_GET['__times__']) + 1 : 1;
if($__times__ > 2) {
  return '';
}
$url .= (strpos($url, '?') === FALSE ? '?' : '&')."__times__=$__times__";
return uc_fopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block);
}
function uc_fopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) {
$return = '';
$matches = parse_url($url);
!isset($matches['host']) && $matches['host'] = '';
!isset($matches['path']) && $matches['path'] = '';
!isset($matches['query']) && $matches['query'] = '';
!isset($matches['port']) && $matches['port'] = '';
$host = $matches['host'];
$path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
$port = !empty($matches['port']) ? $matches['port'] : 80;
if($post) {
  $out = "POST $path HTTP/1.0\r\n";
  $out .= "Accept: */*\r\n";
  //$out .= "Referer: $boardurl\r\n";
  $out .= "Accept-Language: zh-cn\r\n";
  $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
  $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
  $out .= "Host: $host\r\n";
  $out .= 'Content-Length: '.strlen($post)."\r\n";
  $out .= "Connection: Close\r\n";
  $out .= "Cache-Control: no-cache\r\n";
  $out .= "Cookie: $cookie\r\n\r\n";
  $out .= $post;
} else {
  $out = "GET $path HTTP/1.0\r\n";
  $out .= "Accept: */*\r\n";
  //$out .= "Referer: $boardurl\r\n";
  $out .= "Accept-Language: zh-cn\r\n";
  $out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
  $out .= "Host: $host\r\n";
  $out .= "Connection: Close\r\n";
  $out .= "Cookie: $cookie\r\n\r\n";
}
$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
if(!$fp) {
  return '';
} else {
  stream_set_blocking($fp, $block);
  stream_set_timeout($fp, $timeout);
  @fwrite($fp, $out);
  $status = stream_get_meta_data($fp);
  if(!$status['timed_out']) {
   while (!feof($fp)) {
    if(($header = @fgets($fp)) && ($header == "\r\n" ||  $header == "\n")) {
     break;
    }
   }
   $stop = false;
   while(!feof($fp) && !$stop) {
    $data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
    $return .= $data;
    if($limit) {
     $limit -= strlen($data);
     $stop = $limit <= 0;
    }
   }
  }
  @fclose($fp);
  return $return;
}
}
[/php]

5.在ucenter下的index.php根据请求的model和action和appid请求control/user.php 的onsynlogin函数
[php]
function onsynlogin() {
   
  $this->init_input();
  if($this->app['synlogin']) {
   if($this->user = $_ENV['user']->get_user_by_uid($this->input['uid'])) {
    $synstr = '';
    foreach($this->cache['apps'] as $appid => $app) {
     if($app['synlogin'] && $app['appid'] != $this->app['appid']) {
      $synstr .= '<script type="text/javascript" src="'.$app['url'].'/api/uc.php?time='.$this->time.'&code='.urlencode($this->authcode('action=synlogin&username='.$this->user['username'].'&uid='.$this->user['uid'].'&password='.$this->user['password']."&time=".$this->time, 'ENCODE', $app['authkey'])).'"></script>';
     }
    }
    exit("$synstr");
   }
  }
}
[/php]
6.onsynlogin函数通过循环,对系统下的所有应用(在data/cache/setting.php)做JS调用
[php]
$synstr .= '<script type="text/javascript" src="'.$app['url'].'/api/uc.php?time='.$this->time.'&code='.urlencode($this->authcode('action=synlogin&username='.$this->user['username'].'&uid='.$this->user['uid'].'&password='.$this->user['password']." mce_src="'.$app['url'].'/api/uc.php?time='.$this->time.'&code='.urlencode($this->authcode('action=synlogin&username='.$this->user['username'].'&uid='.$this->user['uid'].'&password='.$this->user['password']."&time=".$this->time, 'ENCODE', $app['authkey'])).'"></script>';
[/php]
7.返回到uchome.在每个应用下的api目录有个uc.php文件查找$action == 'synlogin'下面是进行cookie设置
obclean();
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
这两行是必须的
下面setcookie设置cookie
8.这样就在所有ucenter知道的应用下添加了cookie实现了跨域登陆

有不对的地方可以跟帖更正。

过中秋去赶集网上班。希望有个好的开始。



作者: keminar   发布时间: 2008-08-29

为啥没人顶呢。

作者: keminar   发布时间: 2008-08-29

路过学习一下

好东西一定要顶

作者: ssword   发布时间: 2008-08-30

路过顶一下

作者: cfw2005   发布时间: 2008-08-30

谢谢啦。。

作者: keminar   发布时间: 2008-09-01

顶下.
呵...不过,.多讲点这方面的就好了.

作者: liangc   发布时间: 2008-09-01

加了注释就有顶了。

作者: llweiyu   发布时间: 2008-09-05

很好很强大

作者: 落叶人生   发布时间: 2009-01-03

先收藏了。

作者: sinopf   发布时间: 2009-01-03

如此好贴 顶起来

作者: 0hudu   发布时间: 2009-01-03

厉害

作者: E蜗牛   发布时间: 2009-02-06

之前简单测试过,对多标签浏览器没有用
现在看来应该是cookie设置的问题
..go on

作者: yongqi0408   发布时间: 2009-02-06

热门下载

更多