PHP实现的QQ互联、新浪微博、百度账号的账户打通。
<?php
$oauth = new oauth;
$login = strlen($oauth->get('login')) < 1 ? $oauth->post('pf') : $oauth->get('login');
$pfm = array(
'baidu'=>'百度',
'qq'=>'QQ',
'weibo'=>'微博'
);
switch($login){
case 'baidu':$oauth->login($login);break;
case 'qq':$oauth->login($login);break;
case 'weibo':$oauth->login($login);break;
case 'false':$oauth->cookie('oauthUser', true);header('location:'. $oauth->url);break;
default:$user = json_decode($oauth->cookie('oauthUser'), true);
}
echo '<!DOCTYPE>
<html dir="ltr" lang="zh-CN">
<head>
<title>'. (empty($pfm[$user['platf']]) ? '欢迎测试,请选择您的账号类型!' : '['. $pfm[$user['platf']] .']'. $user['name']) .',欢迎回来!</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<style type="text/css">
<!--
*{font-size:16px;font-family:Verdana,Arial,Helvetica,sans-serif;}
body{font-size:12px;color:#616378}
a:link{text-decoration: none;}
a:visited {text-decoration: none;}
a:hover {text-decoration: underline;}
a:active {text-decoration: none;}
div{margin:0 auto;padding:0;width:100%;max-width:960px;}
span{color:#dadada}
img{border:0;border-radius:50%;-webkit-border-radius:50%;-moz-border-radius:50%;box-shadow:0 0.0625rem 0.3125rem rgba(32,33,36,.28);}
-->
</style>
</head>
<body>
<div>
<span>'. ($user['platf']=='qq' ? 'QQ(使用中)' : '<a href="?login=qq" style="color:#0aa858;">QQ</a>') .' | '. ($user['platf'] == 'weibo' ? '微博(使用中)' : '<a href="?login=weibo" style="color:#f4433c;">微博</a>') .' | '.($user['platf']=='baidu' ? '百度(使用中)' : '<a href="?login=baidu" style="color:#2d85f0;">百度</a>') . (empty($user) ? ' | 注销(未登入)' : ' | <a onClick="if(confirm(\'注销该'. $pfm[$user['platf']] .'账户吗?\'))return true;else return false;"href="?login=false" style="color:green;">注销</a>') .'</span>';
echo empty($user) ? '<p>请选择您的账号类型!</p>' : '<p>您好,亲爱的'. $pfm[$user['platf']] .'用户:'. $user['name'] .',感谢您的授权访问!<br />您的身份识别是<strong>'. $user['appid'] .'</strong>,安全密匙是<strong>'. $user['token'] .'</strong>,请妥善保管!</p><img src="'. ($user['platf'] =='baidu' ? 'https://himg.bdimg.com/sys/portrait/item/'. $user['avarat']: $user['avarat']) .'" />';
echo '</div><span id="cnzz_stat_icon_2240791" style="display:none"></span><script async="async" defer="defer" src="https://s11.cnzz.com/stat.php?id=2240791" type="text/javascript"></script></body>
</html>';
class oauth{
/********************************
+ @PHP实现QQ、微博、百度账号的连通+
+ @auther:hi(at)hechaocheng.com +
********************************/
public $post;
public $get;
private $oauth = 'https://oauth.hechaocheng.cn/';
function __construct(){
date_default_timezone_set('PRC');
header('Content-type: text/html; charset=utf-8');
$this->post = $_POST;
$this->get = $_GET;
$this->url = ((!empty($_SERVER['HTTPS'])&&strtolower($_SERVER['HTTPS'])!=='off')?'https://':isset($_SERVER['HTTP_X_FORWARDED_PROTO'])&&$_SERVER['HTTP_X_FORWARDED_PROTO']==='https'?'https://':!empty($_SERVER['HTTP_FRONT_END_HTTPS'])&&strtolower($_SERVER['HTTP_FRONT_END_HTTPS'])!=='off'?'https://':'http://') . $_SERVER['HTTP_HOST'] . str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']). basename(__FILE__);
}
// Login
public function login($pf = 'qq'){
$platform = $this->post('pf');
$appid = $this->post('openid');
$token = $this->post('secret');
$csrf = $this->get('crf');
$_crf = $this->cookie('_CSRF_');
if(!isset($_COOKIE['_CSRF_'])){
$csrf = md5(uniqid(rand(), true));
$_COOKIE['_CSRF_'] = $csrf;
setcookie('_CSRF_', $csrf, time()+99999999, '/');
}
// 构建平台参数
switch($pf){
case 'baidu':
$conf = array(
'pf' => 'baidu',
'lid' => 31,
'ltk' => 72,
'ser' => 'https://openapi.baidu.com/rest/2.0/passport/users/getInfo?appid=%s&access_token=%s',
'ret1' => 'userid',
'ret2' => false,
'avarat' => 'portrait',
'name' => 'username'
);
break;
case 'qq':
$conf = array(
'pf' => 'qq',
'lid' => 32,
'ltk' => 32,
'ser' => 'https://graph.qq.com/user/get_user_info?oauth_consumer_key=100291539&openid=%s&access_token=%s',
'ret1' => 'ret',
'ret2' => 0,
'avarat' => 'figureurl_qq_2',
'name' => 'nickname'
);
break;
case 'weibo':
$conf = array(
'pf' => 'weibo',
'lid' => 10,
'ltk' => 32,
'ser' => 'https://api.weibo.com/2/users/show.json?uid=%s&access_token=%s',
'ret1' => 'id',
'ret2' => false,
'avarat' => 'profile_image_url',
'name' => 'name'
);
break;
// 平台不存在时
default: return;
}
// 判断是否已有登入用户 并且 登入平台
$user = json_decode($this->cookie('oauthUser'), true);
if( (isset($user['platf']) && $user['platf'] != $conf['pf']) || empty($user) ){
// 校验GET的csrf 与 本地生成的CSRF是否一致
if( $csrf === $_crf ){
// 判断GET的openid和token
if(!empty($appid) && strlen($appid) === $conf['lid']) $this->cookie('OPENID', $appid);
if(!empty($token) && strlen($token) === $conf['ltk']) $this->cookie('TOKEN', $token);
}
// 取出本地的openid和token
$uid = $this->cookie('OPENID');
$utk = $this->cookie('TOKEN');
if(empty($uid) || empty($utk)){
// 本地不存在openid或者token时
// 清空已存在的openid 或者 token
$this->cookie('OPENID', true);
$this->cookie('TOKEN', true);
// 发起openid和token请求
header('location:'. $this->oauth .'?pf='. $conf['pf'] .'&ref='. urlencode($this->url) .'&crf='. $_COOKIE['_CSRF_']);
exit;
}
// 用获取到的openid和token查询用户信息
$user = $this->curl(sprintf($conf['ser'], $uid, $utk));
$ret = json_decode($user, true);
$ver = false;
// 数据校验
if($conf['ret2'] === false){
if( !empty($ret[$conf['ret1']])) $ver = true;
}else{
if($ret[$conf['ret1']] === $conf['ret2']) $ver = true;
}
if($ver === true){
// 保存用户信息到本地cookie
$this->cookie('oauthUser',json_encode(array(
'platf' => $pf,
'appid' => $uid,
'token' => $utk,
'avarat' => $ret[$conf['avarat']],
'name' => $ret[$conf['name']]
)));
// 删除已有的openid和token
$this->cookie('OPENID', true);
$this->cookie('TOKEN', true);
header('location:'. $this->url);
exit;
}
}
return $user;
}
// POST
public function post($name = ''){
if(empty($name)) return;
return isset($this->post[$name]) ? $this->post[$name] : NULL;
}
// GET
public function get($name = ''){
if(empty($name)) return;
return isset($this->get[$name]) ? $this->get[$name] : NULL;
}
// cURL
public function curl($url = '', $param = array()){
if(!function_exists('curl_init'))return false;
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
if(count($param) > 0){
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
$res = curl_exec($ch);
$err = curl_error($ch);
if($res === false || $err){
curl_close($ch);
return;
}else{
curl_close($ch);
return $res;
}
}
// COOKIE
public function cookie($name = '', $value = false){
if(empty($name)) return;
if($value === true){
setcookie($name, $value, time()-1, '/');
return;
}
if(strlen($value) > 0){
$_COOKIE[$name] = $value;
setcookie($name, $value, time()+9e9, '/');
}
return isset($_COOKIE[$name]) ? $_COOKIE[$name] : NULL;
}
}
?>