第三方登录 - QQ登录

QQ登录

QQ互联 API官网

返回错误代码说明

    /**
     * qq登录页面
     */
    public function qqLogin(){
        $data=[];
        $callback ='http://www.dome.cn/doQqLogin';
        if(input('get.url')){
            $data['u']=rawurldecode(input('get.url'));
            $str=convert($data);
            $callback.='?'.$str;
        }

        $uData=[
            'response_type' =>  'code',
            'client_id'     =>  '123456789',
            'redirect_uri'  =>  $callback,
            'scope'          =>  'get_user_info',
        ];
        $param=convert($uData);
        $url='https://graph.qq.com/oauth2.0/authorize?'.$param;
        header('location:'.$url);
        exit;
    }

    /**
     * QQ登陆后 的回调处理
     */
    public function doQQLogin(){
        /*实例开始*/
        header('content-type:text/html;charset=utf-8');

        //回调接口,接受QQ服务器返回的信息的脚本
        //$callback 必须和qqLogin里的$callback地址相同(请求参数可以不一样)
        $callback = 'http://www.dome.cn/doQqLogin'; 
        //获取token
        $tokenUrl = 'https://graph.qq.com/oauth2.0/token';
        //获取openid
        $clientUrl='https://graph.qq.com/oauth2.0/me';
        //获取QQ用户信息
        $userInfoUrl='https://graph.qq.com/user/get_user_info';

        //申请QQ互联后得到的APP_ID 和 APP_KEY
        $app_id = '123456789';
        $app_key = '181fasdd61adfabd71sdfasdb78c328e35de';
        //从页面获取code
        $code = isset($_REQUEST['code'])? $_REQUEST['code'] : '';
        if(!$code){
            die('错误的访问。');//如果没有code说明不是qq登录返回的
        }

        //获取token
        $tokenRequestData=[
            'grant_type'=> 'authorization_code',
            'client_id' => $app_id,
            'client_secret' => $app_key,
            'code' => $code,
            'redirect_uri' => $callback,
        ];
        $str=callOnce($tokenUrl,$tokenRequestData,'get');
        parse_str($str,$arr);
        if(!isset($arr['access_token'])){
            die('登陆失败1001');
        }else{
            $token=$arr['access_token'];
            unset($arr);
            unset($str);
        }

        //得到用户的openid(登陆用户的识别码)和Client_id
        $clientUrlRequestData=[
            'access_token'=> $token,
        ];
        $str=callOnce($clientUrl,$clientUrlRequestData,'get');
        if(strpos($str,'callback')!==false){
            $lpos=strpos($str,'(');
            $rpos=strpos($str,')');
            $jsonStr=substr($str,$lpos+1,$rpos - $lpos - 1);
            $arr=json_decode($jsonStr,true);
            $client_id = $arr['client_id'];
            $openid = $arr['openid'];
            unset($arr);
            unset($str);
        }else{
            die('登陆失败1002');
        }

        //获取qq用户信息
        $userInfoRequestData=[
            'oauth_consumer_key' =>   $client_id,
            'access_token'        =>   $token,
            'openid'               =>   $openid,
            'format'               =>   'json',//返回数据类型
        ];
        $str=callOnce($userInfoUrl,$userInfoRequestData);
        $uerInfo=json_decode($str,true);

        //以下为自己的处理逻辑 openid 为唯一标识
        $w=[
            'qq_openid' =>$openid,
        ];
        //通过获取到openid  做其他处理
        if($userInfo = Db::table('shops_user')->field('id,name')->where($w)->find()){
            $um->setLoginSession($userInfo['name']);
        }else{
            $this->doUserReg($openid,$uerInfo);
        }
        //如果登录的返回页面
        if (!empty($_GET['u'])){
            header('location:'.$_GET['u']);exit;
        }else{
            header('location:/');exit;
        }
    }


    //下面用到的是魔法糖函数

    /**
     * url请求
     * @param $url  基础url
     * @param null $args    传递参数(可以为数组)
     * @param string $method    请求类型(post,get)
     * @param bool $withCookie  缓存(默认不开启)
     * @param int $timeout      等待时间
     * @param array $headers    头信息
     * @return mixed
     */
    function callOnce($url, $args=null, $method="post", $withCookie = false, $timeout = 10, $headers=array())
    {
        $ch = curl_init();
        if($method == "post")
        {
            $data = convert($args);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_POST, 1);
        }
        else
        {
            $data = convert($args);
            if($data)
            {
                if(stripos($url, "?") > 0)
                {
                    $url .= "&$data";
                }
                else
                {
                    $url .= "?$data";
                }
            }
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);//禁用https
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if(!empty($headers))
        {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        if($withCookie)
        {
            curl_setopt($ch, CURLOPT_COOKIEJAR, $_COOKIE);
        }
        $r = curl_exec($ch);
        curl_close($ch);
        return $r;
    }

    /**
     * 数组转换为url 参数连接形式 (如穿入[type=>3,id=>6,tid=>10] 返回 type=3&id=6&tid=10 )
     * @param $args 数组
     * @return string
     */
    function convert(&$args)
    {
        $data = '';
        if (is_array($args))
        {
            foreach ($args as $key=>$val)
            {
                if (is_array($val))
                {
                    foreach ($val as $k=>$v)
                    {
                        $data .= $key.'['.$k.']='.rawurlencode($v).'&';
                    }
                }
                else
                {
                    $data .="$key=".rawurlencode($val)."&";
                }
            }
            return trim($data, "&");
        }
        return $args;
    }

猜你喜欢

转载自blog.csdn.net/qq_36308324/article/details/79225618