php使用第三方QQ登录

前言:

PHP实现QQ快速登录,罗列了三种方法

方法一:面向过程,回调地址和首次触发登录写到了一个方法页面【因为有了if做判断】,

        方法二,三:面向对象
            1.先调用登录方法,向腾讯发送请求,
            2.腾讯携带本网站唯一对应参数OPENID,ACCESSTOKEN,返回到对应回调页面,
            3.回调页面接受到腾讯的参数后,通过这个两个参数,再发出对应的请求,如查询用户的数据。
            4.腾讯做出对应的操作,如返回这个用户的数据给你

即使你没看懂,也没关系,按照我下面的流程来,保证你可以实现。


前期准备:

使用人家腾讯的功能,总得和人家打招呼吧!

QQ互联首页:http://connect.qq.com/

进入网址后,按如下操作来:

一.进入官网



二.申请创建【网站】应用




三.按要求填写资料

注意网站地址:填写你要设置快速登录的网址,eg:http://www.test.com;  

回调地址:填写你发送QQ快速登陆后,腾讯得给你信息,这个信息往此页面接受。eg:http://www.test.com/accept_info.php

【详细的申请填写,请见官方提示,这里不做赘述】



四.申请成功后,完善信息

最终要求,获得APP_ID ,APP_KEY


五.代码部分:在你对应的PHP文件内写入,如下


 //方法一,面向过程法
 使用方法:配置$app_id,$app_secret,$my_url后,其他原封复制即可,$user_data为返回的登录信息
 代码:
 
[php]  view plain  copy
  1. //应用的APPID  
  2.            $app_id = "你的APPID";  
  3.            //应用的APPKEY  
  4.            $app_secret = "你的APPKEY";  
  5.            //【成功授权】后的回调地址,即此地址在腾讯的信息中有储存  
  6.            $my_url = "你的回调网址";  
  7.   
  8.            //Step1:获取Authorization Code  
  9.            session_start();  
  10.            $code = $_REQUEST["code"];//存放Authorization Code  
  11.            if(empty($code))  
  12.            {  
  13.                //state参数用于防止CSRF攻击,成功授权后回调时会原样带回  
  14.                $_SESSION['state'] = md5(uniqid(rand(), TRUE));  
  15.                //拼接URL  
  16.                $dialog_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id="  
  17.                    . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="  
  18.                    . $_SESSION['state'];  
  19.                echo("<script> top.location.href='" . $dialog_url . "'</script>");  
  20.            }  
  21.   
  22.            //Step2:通过Authorization Code获取Access Token  
  23.            if($_REQUEST['state'] == $_SESSION['state'] || 1)  
  24.            {  
  25.                //拼接URL  
  26.                $token_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&"  
  27.                    . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)  
  28.                    . "&client_secret=" . $app_secret . "&code=" . $code;  
  29.                $response = file_get_contents($token_url);  
  30.                if (strpos($response"callback") !== false)//如果登录用户临时改变主意取消了,返回true!==false,否则执行step3  
  31.                {  
  32.                    $lpos = strpos($response"(");  
  33.                    $rpos = strrpos($response")");  
  34.                    $response  = substr($response$lpos + 1, $rpos - $lpos -1);  
  35.                    $msg = json_decode($response);  
  36.                    if (isset($msg->error))  
  37.                    {  
  38.                        echo "<h3>error:</h3>" . $msg->error;  
  39.                        echo "<h3>msg  :</h3>" . $msg->error_description;  
  40.                        exit;  
  41.                    }  
  42.                }  
  43.   
  44.                //Step3:使用Access Token来获取用户的OpenID  
  45.                $params = array();  
  46.                parse_str($response$params);//把传回来的数据参数变量化  
  47.                $graph_url = "https://graph.qq.com/oauth2.0/me?access_token=".$params['access_token'];  
  48.                $str  = file_get_contents($graph_url);  
  49.                 if (strpos($str"callback") !== false)  
  50.                 {  
  51.                     $lpos = strpos($str"(");  
  52.                     $rpos = strrpos($str")");  
  53.                     $str  = substr($str$lpos + 1, $rpos - $lpos -1);  
  54.                 }  
  55.                 $user = json_decode($str);//存放返回的数据 client_id  ,openid  
  56.                 if (isset($user->error))  
  57.                 {  
  58.                     echo "<h3>error:</h3>" . $user->error;  
  59.                     echo "<h3>msg  :</h3>" . $user->error_description;  
  60.                     exit;  
  61.                 }  
  62.                 //echo("Hello " . $user->openid);  
  63.                 //echo("Hello " . $params['access_token']);  
  64.   
  65.                //Step4:使用<span style="font-family: Arial, Helvetica, sans-serif;">openid,</span><span style="font-family: Arial, Helvetica, sans-serif;">access_token来获取所接受的用户信息。</span>  
  66.                $user_data_url = "https://graph.qq.com/user/get_user_info?access_token={$params['access_token']}&oauth_consumer_key={$app_id}&openid={$user->openid}&format=json";  
  67.                  
  68.                $user_data = file_get_contents($user_data_url);//此为获取到的user信息  
  69.              }  
  70.              else  
  71.              {  
  72.                  echo("The state does not match. You may be a victim of CSRF.");  
  73.              }  





//方法二。面向对象 使用类QQ_LoginAction.class
    使用方法:
        1.在QQ_LoginAction.class中正确配置 APPID,APPKEY CALLBACK(回调网址)
        2.在调用方法中,代码:
         
[php]  view plain  copy
  1. $qq_login = new \Component\QQ_LoginAction();        //引入此类文件即可  
  2. $qq_login->qq_login();                   //调用登录方法,向腾讯发出快速登录请求  


        3.在回调页面中,代码:
            
[php]  view plain  copy
  1. $qc = new \Component\QQ_LoginAction();  
  2. $acs = $qc->qq_callback();<span style="white-space:pre">       //access_token  
  3. $oid=$qc->get_openid();<span style="white-space:pre">          //openid  
  4. $user_data = $qc->get_user_info();<span style="white-space:pre">   //get_user_info()为获得该用户的信息,其他操作方法见API文档  


        4.$user_data即为返回的用户数据。

5.QQ_LoginAction.class.php 文件代码:【用的ThinkPHP3.2】

[php]  view plain  copy
  1. <?php  
  2. namespace Component;  
  3.   
  4. session_start();  
  5. define('APPID','XXXX');         //appid  
  6. define('APPKEY','XXXX');        //appkey  
  7. define('CALLBACK','XXXX');      //回调地址  
  8. define('SCOPE','get_user_info,list_album,add_album,upload_pic,add_topic,add_weibo');      //授权接口列表  
  9. class QQ_LoginAction {  
  10.     const GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";  
  11.     const GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token";  
  12.     const GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me";  
  13.     private  $APIMap = array(  
  14.         "get_user_info" => array(          //获取用户资料  
  15.             "https://graph.qq.com/user/get_user_info",  
  16.             array("format" => "json"),  
  17.         ),  
  18.         "add_t" => array(                //发布一条普通微博  
  19.             "https://graph.qq.com/t/add_t",  
  20.             array("format" => "json""content","#clientip","#longitude","#latitude","#compatibleflag"),  
  21.             "POST"  
  22.         ),  
  23.         "add_pic_t" => array(             //发布一条图片微博  
  24.             "https://graph.qq.com/t/add_pic_t",  
  25.             array("content""pic""format" => "json""#clientip""#longitude""#latitude""#syncflag""#compatiblefalg"),  
  26.             "POST"  
  27.         ),  
  28.         "del_t" => array(                     //删除一条微博  
  29.             "https://graph.qq.com/t/del_t",  
  30.             array("id""format" => "json"),  
  31.             "POST"  
  32.         ),  
  33.         "get_repost_list" => array(             //获取单条微博的转发或点评列表  
  34.             "https://graph.qq.com/t/get_repost_list",  
  35.             array("flag""rootid""pageflag""pagetime""reqnum""twitterid""format" => "json")  
  36.         ),  
  37.         "get_info" => array(                  //获取当前用户资料  
  38.             "https://graph.qq.com/user/get_info",  
  39.             array("format" => "json")  
  40.         ),  
  41.         "get_other_info" => array(               //获取其他用户资料  
  42.             "https://graph.qq.com/user/get_other_info",  
  43.             array("format" => "json""#name-1""#fopenid-1")  
  44.         ),  
  45.         "get_fanslist" => array(  
  46.             "https://graph.qq.com/relation/get_fanslist",   //我的微博粉丝列表  
  47.             array("format" => "json""reqnum""startindex""#mode""#install""#sex")  
  48.         ),  
  49.         "get_idollist" => array(  
  50.             "https://graph.qq.com/relation/get_idollist",   //我的微博收听列表  
  51.             array("format" => "json""reqnum""startindex""#mode""#install")  
  52.         ),  
  53.         "add_idol" => array(  
  54.             "https://graph.qq.com/relation/add_idol",     //微博收听某用户  
  55.             array("format" => "json""#name-1""#fopenids-1"),  
  56.             "POST"  
  57.         ),  
  58.         "del_idol" => array(          //微博取消收听某用户  
  59.             "https://graph.qq.com/relation/del_idol",  
  60.             array("format" => "json""#name-1""#fopenid-1"),  
  61.             "POST"  
  62.         )  
  63.     );  
  64.     private $keysArr;  
  65.     function __construct(){  
  66.         if($_SESSION["openid"]){  
  67.             $this->keysArr = array(  
  68.                 "oauth_consumer_key" => APPID,  
  69.                 "access_token" => $_SESSION['access_token'],  
  70.                 "openid" => $_SESSION["openid"]  
  71.             );  
  72.         }else{  
  73.             $this->keysArr = array(  
  74.                 "oauth_consumer_key" => APPID  
  75.             );  
  76.         }  
  77.     }  
  78.     public function qq_login(){  
  79.         //-------生成唯一随机串防CSRF攻击  
  80.         $_SESSION['state'] = md5(uniqid(rand(), TRUE));  
  81.         $keysArr = array(  
  82.             "response_type" => "code",  
  83.             "client_id" => APPID,  
  84.             "redirect_uri" => CALLBACK,  
  85.             "state" => $_SESSION['state'],  
  86.             "scope" => SCOPE  
  87.         );  
  88.         $login_url = self::GET_AUTH_CODE_URL.'?'.http_build_query($keysArr);  
  89.         header("Location:$login_url");  
  90.     }  
  91.     public function qq_callback(){  
  92.         //--------验证state防止CSRF攻击  
  93.         if($_GET['state'] != $_SESSION['state']){  
  94.             return false;  
  95.         }  
  96.         //-------请求参数列表  
  97.         $keysArr = array(  
  98.             "grant_type" => "authorization_code",  
  99.             "client_id" => APPID,  
  100.             "redirect_uri" => CALLBACK,  
  101.             "client_secret" => APPKEY,  
  102.             "code" => $_GET['code']  
  103.         );  
  104.         //------构造请求access_token的url  
  105.         $token_url = self::GET_ACCESS_TOKEN_URL.'?'.http_build_query($keysArr);  
  106.         $response = $this->get_contents($token_url);  
  107.         if(strpos($response"callback") !== false){  
  108.             $lpos = strpos($response"(");  
  109.             $rpos = strrpos($response")");  
  110.             $response  = substr($response$lpos + 1, $rpos - $lpos -1);  
  111.             $msg = json_decode($response);  
  112.             if(isset($msg->error)){  
  113.                 $this->showError($msg->error, $msg->error_description);  
  114.             }  
  115.         }  
  116.         $params = array();  
  117.         parse_str($response$params);  
  118.         $_SESSION["access_token"]=$params["access_token"];  
  119.         $this->keysArr['access_token']=$params['access_token'];  
  120.         return $params["access_token"];  
  121.     }  
  122.   
  123.     public function get_contents($url){  
  124.         if (ini_get("allow_url_fopen") == "1") {  
  125.             $response = file_get_contents($url);  
  126.         }else{  
  127.             $ch = curl_init();  
  128.             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  
  129.             curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  
  130.             curl_setopt($ch, CURLOPT_URL, $url);  
  131.             $response =  curl_exec($ch);  
  132.             curl_close($ch);  
  133.         }  
  134.         if(empty($response)){  
  135.             return false;  
  136.         }  
  137.         return $response;  
  138.     }  
  139.     public function get_openid(){  
  140.         //-------请求参数列表  
  141.         $keysArr = array(  
  142.             "access_token" => $_SESSION["access_token"]  
  143.         );  
  144.         $graph_url = self::GET_OPENID_URL.'?'.http_build_query($keysArr);  
  145.         $response = $this->get_contents($graph_url);  
  146.         //--------检测错误是否发生  
  147.         if(strpos($response"callback") !== false){  
  148.             $lpos = strpos($response"(");  
  149.             $rpos = strrpos($response")");  
  150.             $response = substr($response$lpos + 1, $rpos - $lpos -1);  
  151.         }  
  152.         $user = json_decode($response);  
  153.         if(isset($user->error)){  
  154.             $this->showError($user->error, $user->error_description);  
  155.         }  
  156.         //------记录openid  
  157.         $_SESSION['openid']=$user->openid;  
  158.         $this->keysArr['openid']=$user->openid;  
  159.         return $user->openid;  
  160.     }  
  161.   
  162.     /** 
  163.      * showError 
  164.      * 显示错误信息 
  165.      * @param int $code    错误代码 
  166.      * @param string $description 描述信息(可选) 
  167.      */  
  168.     public function showError($code$description = '$'){  
  169.             echo "<meta charset=\"UTF-8\">";  
  170.             echo "<h3>error:</h3>$code";  
  171.             echo "<h3>msg  :</h3>$description";  
  172.             exit();  
  173.     }  
  174.   
  175.     /** 
  176.      * _call 
  177.      * 魔术方法,做api调用转发 
  178.      * @param string $name    调用的方法名称 
  179.      * @param array $arg      参数列表数组 
  180.      * @since 5.0 
  181.      * @return array          返加调用结果数组 
  182.      */  
  183.     public function __call($name,$arg){  
  184.         //如果APIMap不存在相应的api  
  185.         if(empty($this->APIMap[$name])){  
  186.             $this->showError("api调用名称错误","不存在的API: <span style='color:red;'>$name</span>");  
  187.         }  
  188.         //从APIMap获取api相应参数  
  189.         $baseUrl = $this->APIMap[$name][0];  
  190.         $argsList = $this->APIMap[$name][1];  
  191.         $method = isset($this->APIMap[$name][2]) ? $this->APIMap[$name][2] : "GET";  
  192.         if(empty($arg)){  
  193.             $arg[0] = null;  
  194.         }  
  195.        $responseArr = json_decode($this->_applyAPI($arg[0], $argsList$baseUrl$method),true);  
  196.         //检查返回ret判断api是否成功调用  
  197.         if($responseArr['ret'] == 0){  
  198.             return $responseArr;  
  199.         }else{  
  200.             $this->showError($responseArr['ret'], $responseArr['msg']);  
  201.         }  
  202.     }  
  203.   
  204.     //调用相应api  
  205.     private function _applyAPI($arr$argsList$baseUrl$method){  
  206.         $pre = "#";  
  207.         $keysArr = $this->keysArr;  
  208.         $optionArgList = array();//一些多项选填参数必选一的情形  
  209.         foreach($argsList as $key => $val){  
  210.             $tmpKey = $key;  
  211.             $tmpVal = $val;  
  212.             if(!is_string($key)){  
  213.                 $tmpKey = $val;  
  214.                 if(strpos($val,$pre) === 0){  
  215.                     $tmpVal = $pre;  
  216.                     $tmpKey = substr($tmpKey,1);  
  217.                     if(preg_match("/-(\d$)/"$tmpKey$res)){  
  218.                         $tmpKey = str_replace($res[0], ""$tmpKey);  
  219.                         $optionArgList[]= $tmpKey;  
  220.                     }  
  221.                 }else{  
  222.                     $tmpVal = null;  
  223.                 }  
  224.             }  
  225.             //-----如果没有设置相应的参数  
  226.             if(!isset($arr[$tmpKey]) || $arr[$tmpKey] === ""){  
  227.                 if($tmpVal == $pre){  
  228.                     continue;  
  229.                 }else if($tmpVal){//则使用默认的值  
  230.                     $arr[$tmpKey] = $tmpVal;  
  231.                 }else{  
  232.                     $this->showError("api调用参数错误","未传入参数$tmpKey");  
  233.                 }  
  234.             }  
  235.             $keysArr[$tmpKey] = $arr[$tmpKey];  
  236.         }  
  237.         //检查选填参数必填一的情形  
  238.         if(count($optionArgList)!=0){  
  239.             $n = 0;  
  240.             foreach($optionArgList as $val){  
  241.                 if(in_array($valarray_keys($keysArr))){  
  242.                     $n++;  
  243.                 }  
  244.             }  
  245.             if(!$n){  
  246.                 $str = implode(",",$optionArgList);  
  247.                 $this->showError("api调用参数错误",$str."必填一个");  
  248.             }  
  249.         }  
  250.         if($method == "POST"){  
  251.             $response = $this->post($baseUrl$keysArr, 0);  
  252.         }else if($method == "GET"){  
  253.             $baseUrl=$baseUrl.'?'.http_build_query($keysArr);  
  254.             $response = $this->get_contents($baseUrl);  
  255.         }  
  256.         return $response;  
  257.     }  
  258.   
  259.     public function post($url$keysArr$flag = 0){  
  260.         $ch = curl_init();  
  261.         if(! $flag) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  
  262.         curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  
  263.         curl_setopt($ch, CURLOPT_POST, TRUE);  
  264.         curl_setopt($ch, CURLOPT_POSTFIELDS, $keysArr);  
  265.         curl_setopt($ch, CURLOPT_URL, $url);  
  266.         $ret = curl_exec($ch);  
  267.         curl_close($ch);  
  268.         return $ret;  
  269.     }  
  270. }   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值