1.QQ封装类
<?php
class QQ{
public static $version = "2.0";
public static $getAuthCodeUrl = "https://graph.qq.com/oauth2.0/authorize";
public static $getAccessTokenUrl = "https://graph.qq.com/oauth2.0/token";
public static $getOpenIDUrl = "https://graph.qq.com/oauth2.0/me";
public static $getUserInfoUrl = "https://graph.qq.com/user/get_user_info";
public static function do_post($url, $data){
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_URL, $url);
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}
public static function get_url_contents($url){
if (ini_get("allow_url_fopen") == "1")
return file_get_contents($url);
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
public static function combineURL($baseURL,$keysArr){
$combined = $baseURL."?";
$valueArr = [];
foreach($keysArr as $key => $val){
$valueArr[] = "$key=$val";
}
$keyStr = implode("&",$valueArr);
$combined .= ($keyStr);
return $combined;
}
public $config;
public function setSession($key,$val){
session_start();
if(!array_key_exists('QQOauth', $_SESSION))
$_SESSION['QQOauth']=[];
$_SESSION['QQOauth'][$key]=$val;
}
public function getSession($key){
session_start();
if(!array_key_exists('QQOauth', $_SESSION))
$_SESSION['QQOauth']=[];
if(array_key_exists($key, $_SESSION['QQOauth']))
return $_SESSION['QQOauth'][$key];
return false;
}
public function __construct($config){
$this->config=$config;
}
public function getAuthCode(){
$appid = $this->config["appid"];
$callback = $this->config["callback"];
$scope = "get_user_info";
//-------生成唯一随机串防CSRF攻击
$state = md5(uniqid(rand(), TRUE));
$this->setSession("state",$state);
//-------构造请求参数列表
$keysArr = [
"response_type" => "code",
"client_id" => $appid,
"redirect_uri" => $callback,
"state" => $state,
"scope" => $scope
];
$login_url = self::combineURL(self::$getAuthCodeUrl, $keysArr);
return $login_url;
}
public function getAccessToken($code,$state){
// $states = $this->getSession("state");
//--------验证state防止CSRF攻击
// if(!$states || $states != $state){
// return false;
// }
//-------请求参数列表
$keysArr = [
"grant_type" => "authorization_code",
"client_id" => $this->config["appid"],
"redirect_uri" => urlencode($this->config["callback"]),
"client_secret" => $this->config["appkey"],
"code" => $code
];
//------构造请求access_token的url
$token_url = self::combineURL(self::$getAccessTokenUrl, $keysArr);
$response = self::get_url_contents($token_url);
if(strpos($response, "callback") !== false){
$lpos = strpos($response, "(");
$rpos = strrpos($response, ")");
$response = substr($response, $lpos + 1, $rpos - $lpos -1);
$msg = json_decode($response);
if(isset($msg->error)){
return false;
}
}
$params = [];
parse_str($response, $params);
return $params["access_token"];
}
public function getOpenID($access_token){
//-------请求参数列表
$keysArr = ["access_token" => $access_token];
$graph_url = self::combineURL(self::$getOpenIDUrl, $keysArr);
$response = self::get_url_contents($graph_url);
//--------检测错误是否发生
if(strpos($response, "callback") !== false){
$lpos = strpos($response, "(");
$rpos = strrpos($response, ")");
$response = substr($response, $lpos + 1, $rpos - $lpos -1);
}
$user = json_decode($response);
if(isset($user->error)){
return false;
}
return $user->openid;
}
public function getUserInfo($access_token,$openid){
//-------请求参数列表
$appid = $this->config["appid"];
$keysArr = [
"access_token" => $access_token,
"oauth_consumer_key" => $appid,
"openid" => $openid
];
$graph_url = self::combineURL(self::$getUserInfoUrl, $keysArr);
$response = self::get_url_contents($graph_url);
//--------检测错误是否发生
if(strpos($response, "callback") !== false){
$lpos = strpos($response, "(");
$rpos = strrpos($response, ")");
$response = substr($response, $lpos + 1, $rpos - $lpos -1);
}
$user = json_decode($response);
if(isset($user->error)){
return false;
}
return $user;
}
}
2. 控制器代码
//qq第三方登陆ak
private $qq;
private $qqConfig=[
'appid'=>"********",
'appkey'=>"**************************",
'callback'=>"http://www.baidu.com/thinkphp/public/index.php/bshy_web/user/notify" //回调地址
];
function __construct(){
parent::__construct();
vendor("qqconnect.QQ");
$qqConfig = $this->qqConfig;
//$qqConfig['callback']=url("http://www.baidu.com/thinkphp/public/index.php/bshy_web/user/notify",false,true,true);
$this->qq = new \QQ($qqConfig);
}
//获取QQ二维码
public function qqLogin(){
$response = request();
$data = $response->param();
if(!empty($data['uid'])){
Cache::set('uid',$data['uid']); //存到Cache
}
$url = $this->qq->getAuthCode();
//print_r($url);die;
header("Location:".$url);
}
//QQ绑定的回调地址
public function notify(){
vendor("qqconnect.QQ");
$param = $this->request->param();
$code = $param['code'];
$state = $param['state'];
$qqConfig = $this->qqConfig;
$qq = new \QQ($qqConfig);
$accessToken = $qq->getAccessToken($code,$state);
if(!$accessToken){
$this->error("非法操作");
}
$openid = $qq->getOpenID($accessToken);
//print_r($openid);die;
//$tencent_userInfo=$qq->getUserInfo($accessToken,$openid);
//$userInfo = json_decode(json_encode($tencent_userInfo),true);
$userInfo['openid']=$openid;
$userInfo['unionid']=$openid;
$uid=Cache::get('uid');
Cache::clear();
if(!empty($uid)){
$this->user_qq($userInfo,$uid);
}else{
$this->dealWithQqLogin($userInfo);
}
}
/**
* 根据QQ授权用户的信息 进行下一步的梳理
* @param $user_info
*/
public function dealWithQqLogin($user_info){
//判断此微信是否在平台绑定
$is_user=Db::name('ucenter_member')->where('qq_openid',$user_info['openid'])->where('qq_unionid',$user_info['unionid'])->find();
//绑定直接登陆,没绑定注册
if(!empty($is_user)){
$token=build_auth_key();
$array['token'] =$token;
$array['token_time'] = time();
$uid=$is_user['id'];
Db::name('ucenter_member')->where('id',$uid)->update($array);
header("Location: http://www.baidu.com/login?uid=$uid&token=$token&type=1");
}else{
header("Location: http://www.baidu.com/login?type=0&openid=".$user_info['openid']."&unionid=".$user_info['unionid']."&status=2");
}
}
//个人中心绑定QQ
public function user_qq($user_info,$uid){
$array['qq_openid'] =$user_info['openid'];
$array['qq_unionid'] = $user_info['unionid'];
$token=Db::name('ucenter_member')->where('id',$uid)->value('token');
$is_qq=Db::name('ucenter_member')->where('qq_openid',$user_info['openid'])->where('qq_unionid',$user_info['unionid'])->find();
if(!empty($is_qq)){
header("Location: http://www.baidu.com/person/user/userBind?uid=$uid&token=$token&type=2");
die;
}
$re=Db::name('ucenter_member')->where('id',$uid)->update($array);
if(!empty($re)){
header("Location: http://www.baidu.com/person/user/userBind?uid=$uid&token=$token&type=1");
}else{
header("Location: http://www.baidu.com/person/user/userBind?uid=$uid&token=$token&type=0");
}
}
//QQ解绑
public function jie_qq(){
$check_status = $this->status;
if ($check_status != 200) {
$msg = $this->msg;
if ($check_status != 0) {
$check_status = 2;
} else {
$check_status = 0;
}
return json(['status' => $check_status, 'msg' => $msg, 'info' => '']);
}
$data = $this->data;
$status=1;
$msg='解绑成功';
$array['qq_openid'] ='';
$array['qq_unionid'] = '';
$info=Db::name('ucenter_member')->where('id',$data['uid'])->update($array);
if(!$info){
$status=0;
$msg='解绑失败';
}
return json(['status'=>$status,'msg'=>$msg,'info'=>$info]);
}