pc网站qq互联登录授权php版

首先看下工具类

<?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',#获取用户基本信息
    ];
    #appid
    private $appid;
    #appkey
    private $appkey;
    #请求用户授权时向用户显示的可进行授权的列表get_user_info,list_album...逗号分开,默认get_user_info
    private $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)accesstokencode13.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如下图,说明你已调用成功

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值