牛骨文教育服务平台(让学习变的简单)
博文笔记

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

创建时间:2014-01-22 投稿人: 浏览次数:203
<?php
/**
 * 1.每一个应用都要包含uc_client,下面拿uchome代码举例
 * 2.uchome登陆时访问source/do_login.php 的getpassport函数,getpassport通过uc_client 直接连ucenter的数据库,实现当前站点的登陆
 * 3.uchome然后调用$ucsynlogin = uc_user_synlogin ( $setarr ["uid"] );
 * 4.实现跨域登陆
 * 
 */

//跨越请求api
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;
}
 
//在uc_user_synlogin函数里再用uc_client/client.php的fsockopen去访问ucenter下的index.php默认超时15秒
 
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);
}

//fsockopen请求
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
";
		$out .= "Accept: */*
";
		//$out .= "Referer: $boardurl
";
		$out .= "Accept-Language: zh-cn
";
		$out .= "Content-Type: application/x-www-form-urlencoded
";
		$out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]
";
		$out .= "Host: $host
";
		$out .= "Content-Length: ".strlen($post)."
";
		$out .= "Connection: Close
";
		$out .= "Cache-Control: no-cache
";
		$out .= "Cookie: $cookie

";
		$out .= $post;
	} else {
		$out = "GET $path HTTP/1.0
";
		$out .= "Accept: */*
";
		//$out .= "Referer: $boardurl
";
		$out .= "Accept-Language: zh-cn
";
		$out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]
";
		$out .= "Host: $host
";
		$out .= "Connection: Close
";
		$out .= "Cookie: $cookie

";
	}
	$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 == "
" ||  $header == "
")) {
					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;
	}
}
 
//在ucenter下的index.php根据请求的model和action和appid请求control/user.php 的onsynlogin函数
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");
		}
	}
}
 
// onsynlogin函数通过循环,对系统下的所有应用(在data/cache/setting.php)做JS调用
$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>";

//返回到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
//这样就在所有ucenter知道的应用下添加了cookie实现了跨域登陆
 


声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。