首先看下工具类
<?php
/*** QQ互联pc网页授权类*/
namespace App\Lib\QQconnect;use App\Lib\Util\Curl;class QQconnect{const err = [0 =>'成功',100000 => '缺少参数response_type或response_type非法',100001 => '缺少参数client_id',100002 => '缺少参数client_secret',100003 => 'http head中缺少Authorization',100004 => '缺少参数grant_type或grant_type非法',100005 => '缺少参数code',100006 => '缺少refresh token',100007 => '缺少access token',100008 => '该appid不存在',100009 => 'client_secret(即appkey)非法',100010 => '回调地址不合法,常见原因请见:回调地址常见问题及修改方法',100011 => 'APP不处于上线状态',100012 => 'HTTP请求非post方式',100013 => 'access token非法',100014 => 'access token过期。 token过期时间为3个月。如果存储的access token过期,请重新走登录流程,根据使用Authorization_Code获取Access_Token或使用Implicit_Grant方式获取Access_Token获取新的access token值',100015 => 'access token废除。 token被回收,或者被用户删除。请重新走登录流程,根据使用Authorization_Code获取Access_Token或使用Implicit_Grant方式获取Access_Token获取新的access token值',100016 => 'access token验证失败',100017 => '获取appid失败',100018 => '获取code值失败',100019 => '用code换取access token值失败',100020 => 'code被重复使用',100021 => '获取access token值失败',100022 => '获取refresh token值失败',100023 => '获取app具有的权限列表失败',100024 => '获取某OpenID对某appid的权限列表失败',100025 => '获取全量api信息、全量分组信息',100026 => '设置用户对某app授权api列表失败',100027 => '设置用户对某app授权时间失败',100028 => '缺少参数which',100029 => '错误的http请求',100030 => '用户没有对该api进行授权,或用户在腾讯侧删除了该api的权限。请用户重新走登录、授权流程,对该api进行授权',100031 => '第三方应用没有对该api操作的权限。请发送邮件进行OpenAPI权限申请',100032 => '过载,一开始未细分时可以用',100033 => '缺少UIN参数',100034 => '缺少skey参数',100035 => '用户未登陆',100036 => 'RefreshToken失效',100037 => 'RefreshToken已过期',100038 => 'RefreshToken已废除',100039 => 'RefreshToken到达调用上限',100040 => 'RefreshToken的AppKey非法',100041 => 'RefreshToken的AppID非法',100042 => 'RefreshToken非法',100043 => 'APP处于暂停状态',100044 => 'Md5校验失败',100045 => '用户改密token失效',100046 => 'g_tk校验失败',100048 => '没有设置companyID',100049 => 'APPID没有权限(get_unionid)',100050 => 'OPENID解密失败,一般是openid和appid不匹配',100051 => '调试模式无权限'];#接口地址const LINK = ['oauth' => 'https://graph.qq.com/oauth2.0/authorize',#获取Authorization Code'getAccessToken' => 'https://graph.qq.com/oauth2.0/token',#获取或刷新Access Token'getOpenid' => 'https://graph.qq.com/oauth2.0/me',#access_token'getUserInfo' => 'https://graph.qq.com/user/get_user_info',#获取用户基本信息];#appidprivate $appid;#appkeyprivate $appkey;#请求用户授权时向用户显示的可进行授权的列表get_user_info,list_album...逗号分开,默认get_user_infoprivate $scope;#回调地址(务必于应用上填写的一致)private $redirect_uri;#错误代码private $errcode;#错误信息private $errmsg;#单例private static $_instance;private function __construct($appid,$appkey){$this->appid = $appid;$this->appkey = $appkey;}private function __clone(){}public static function main(){if(!isset(self::$_instance)){if(func_num_args()<2){exit('实例化-参数个数错误!');}$args = func_get_args();self::$_instance = new self($args[0],$args[1]);}return self::$_instance;}/***获取错误信息代码** @param string|array $flag 1:错误代码,2:错误信息,others:数组* @return string|array*/public function getError($flag=0){switch ($flag){case 0:$errmsg = $this->errmsg;break;case 1:$errmsg = $this->errcode;break;default:$errmsg = ['errcode' => $this->errcode,'errmsg' => $this->errmsg];break;}return $errmsg;}#设置回调地址public function setRedirectUri($uri){$this->redirect_uri = $uri;}#获取回调地址public function getRedirectUri(){return $this->redirect_uri;}/***setScope 设置授权列表** @param string|array $scope 授权列表,逗号分隔* @return void*/public function setScope($scope){if(is_array($scope)){$scope = implode(',',$scope);}$this->scope =$scope;}#获取授权列表 true 数组,默认false 逗号分隔字符串public function getScope($flag=false){if($flag){return explode(',',$this->scope);}return $this->scope;}/***getOauthUrl 获取授权地址*/public function getOauthUrl($state=null,$display=null){$keysArr = ['response_type' => 'code','client_id' => $this->appid,'state' => $state,'redirect_uri' => urlencode($this->redirect_uri),'display' => $display,'scope' => $this->scope];return self::combineURL(self::LINK['oauth'],$keysArr);}/***getAccessToken 通过code获取access_token** @param string $code 授权获取的code* @return string*/public function getAccessToken($code){$keysArr = ['grant_type' => 'authorization_code','client_id' => $this->appid,'client_secret' => $this->appkey,'redirect_uri' => urlencode($this->redirect_uri),'code' => $code];$link = self::combineURL(self::LINK['getAccessToken'],$keysArr);$resData = Curl::main()->get($link);//--------检测错误是否发生if(strpos($resData, "callback") !== false){$lpos = strpos($resData, "(");$rpos = strrpos($resData, ")");$resData = substr($resData, $lpos + 1, $rpos - $lpos -1);$resData = json_decode($resData,true);if(isset($resData['error'])){$this->errcode = $resData['error'];$this->errmsg = self::err[$resData['error']];return false;}}else{parse_str($resData,$param);return $param['access_token'];}}/***getUserOpenid 通过access_token获取用户openid** @param string $access_token* @return string*/public function getUserOpenid($access_token){$link = self::combineURL(self::LINK['getOpenid'],['access_token'=>$access_token]);$response = Curl::main()->get($link);//--------检测错误是否发生if(strpos($response, "callback") !== false){$lpos = strpos($response, "(");$rpos = strrpos($response, ")");$response = substr($response, $lpos + 1, $rpos - $lpos -1);}$user = json_decode($response,true);if(isset($user['error'])){$this->errcode = $user['code'];$this->errmsg = self::err[$user['code']];return false;}return $user['openid'];}/***getUserInfo 获取用户基本信息** @param string $access_token* @param string $openid* @return boolean|array*/public function getUserInfo($access_token,$openid){$link = self::combineURL(self::LINK['getUserInfo'],['access_token' => $access_token,'oauth_consumer_key' => $this->appid,'openid' => $openid]);$resData = Curl::main()->get($link);return self::checkResult($resData);}/***checkResult 请求结果处理** @param string $resData 待检测数据* @return boolean|array*/public function checkResult($resData){$resData = json_decode($resData,true);if(!$resData || $resData['ret']!=0){$this->errcode = $resData['ret'];$this->errmsg = $resData['msg'];return false;}else{return $resData;}}/*** combineURL 拼接url* @param string $baseURL 基于的url* @param array $keysArr 参数列表数组* @return string 返回拼接的url*/public static function combineURL($baseURL,$keysArr){$combined = $baseURL."?";$valueArr = array();foreach($keysArr as $key => $val){$valueArr[] = "$key=$val";}$keyStr = implode("&",$valueArr);$combined .= ($keyStr);return $combined;}
}
注意
* 其中用到Curl类,主要实现get或post请求,file_get_contents效果一样
1. getOauthUrl(),获取授权地址
2. getAccessToken( code),获取accesstoken,code为1中授权后回调地址中携带参数3.getUserOpenid( access_token),获取用户openid,需2中accesstoken
4. getUserInfo( accesstoken, openid),需2,3不中的accesstoken和openid
具体调用方法(laravel版)
<?php
/*** PC网站QQ登录授权**/
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Lib\QQconnect\QQconnect;
use Illuminate\Http\Request;class QQoauthController extends Controller{const APPID = '你自己的appid’;const APPKEY = '你自己的APPKEY ';const REDIRECT_URI = '你自己的回调地址';const SCOPE = 'get_user_info';const STATE = 'test';private $qqconnect;public function __construct(){$this->qqconnect = QQconnect::main(self::APPID,self::APPKEY);$this->qqconnect->setRedirectUri(self::REDIRECT_URI);$this->qqconnect->setScope(self::SCOPE);}/***授权获取code*/public function index(Request $request){if(!$request->has('state')){header('Location:'.$this->qqconnect->getOauthUrl(self::STATE));}else{$code = $request->input('code');$state = $request->input('state');if($state != self::STATE ){exit('非法操作!');}#获取access_token$access_token = $this->qqconnect->getAccessToken($code);if(!$access_token){exit($this->qqconnect->getError());}#获取openid$openid = $this->qqconnect->getUserOpenid($access_token);if(!$openid){exit($this->qqconnect->getError());}#获取用户基本信息$userinfo =$this->qqconnect->getUserInfo($access_token,$openid);if(!$userinfo){exit($this->qqconnect->getError());}session(['userinfo'=>$userinfo]);return redirect()->route('index');}}
}
看到$userinfo如下图,说明你已调用成功