php使用第三方QQ登入
執法丶大隊發表於2020-04-06
前言:
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為返回的登入資訊
程式碼:
- //應用的APPID
- $app_id = "你的APPID";
- //應用的APPKEY
- $app_secret = "你的APPKEY";
- //【成功授權】後的回撥地址,即此地址在騰訊的資訊中有儲存
- $my_url = "你的回撥網址";
- //Step1:獲取Authorization Code
- session_start();
- $code = $_REQUEST["code"];//存放Authorization Code
- if(empty($code))
- {
- //state引數用於防止CSRF攻擊,成功授權後回撥時會原樣帶回
- $_SESSION['state'] = md5(uniqid(rand(), TRUE));
- //拼接URL
- $dialog_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id="
- . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
- . $_SESSION['state'];
- echo("<script> top.location.href='" . $dialog_url . "'</script>");
- }
- //Step2:通過Authorization Code獲取Access Token
- if($_REQUEST['state'] == $_SESSION['state'] || 1)
- {
- //拼接URL
- $token_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&"
- . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
- . "&client_secret=" . $app_secret . "&code=" . $code;
- $response = file_get_contents($token_url);
- if (strpos($response, "callback") !== false)//如果登入使用者臨時改變主意取消了,返回true!==false,否則執行step3
- {
- $lpos = strpos($response, "(");
- $rpos = strrpos($response, ")");
- $response = substr($response, $lpos + 1, $rpos - $lpos -1);
- $msg = json_decode($response);
- if (isset($msg->error))
- {
- echo "<h3>error:</h3>" . $msg->error;
- echo "<h3>msg :</h3>" . $msg->error_description;
- exit;
- }
- }
- //Step3:使用Access Token來獲取使用者的OpenID
- $params = array();
- parse_str($response, $params);//把傳回來的資料引數變數化
- $graph_url = "https://graph.qq.com/oauth2.0/me?access_token=".$params['access_token'];
- $str = file_get_contents($graph_url);
- if (strpos($str, "callback") !== false)
- {
- $lpos = strpos($str, "(");
- $rpos = strrpos($str, ")");
- $str = substr($str, $lpos + 1, $rpos - $lpos -1);
- }
- $user = json_decode($str);//存放返回的資料 client_id ,openid
- if (isset($user->error))
- {
- echo "<h3>error:</h3>" . $user->error;
- echo "<h3>msg :</h3>" . $user->error_description;
- exit;
- }
- //echo("Hello " . $user->openid);
- //echo("Hello " . $params['access_token']);
- //Step4:使用<span style="font-family: Arial, Helvetica, sans-serif;">openid,</span><span style="font-family: Arial, Helvetica, sans-serif;">access_token來獲取所接受的使用者資訊。</span>
- $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";
- $user_data = file_get_contents($user_data_url);//此為獲取到的user資訊
- }
- else
- {
- echo("The state does not match. You may be a victim of CSRF.");
- }
//方法二。物件導向 使用類QQ_LoginAction.class
使用方法:
1.在QQ_LoginAction.class中正確配置 APPID,APPKEY CALLBACK(回撥網址)
2.在呼叫方法中,程式碼:
- $qq_login = new \Component\QQ_LoginAction(); //引入此類檔案即可
- $qq_login->qq_login(); //呼叫登入方法,向騰訊發出快速登入請求
3.在回撥頁面中,程式碼:
- $qc = new \Component\QQ_LoginAction();
- $acs = $qc->qq_callback();<span style="white-space:pre"> //access_token
- $oid=$qc->get_openid();<span style="white-space:pre"> //openid
- $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
- namespace Component;
- session_start();
- define('APPID','XXXX'); //appid
- define('APPKEY','XXXX'); //appkey
- define('CALLBACK','XXXX'); //回撥地址
- define('SCOPE','get_user_info,list_album,add_album,upload_pic,add_topic,add_weibo'); //授權介面列表
- class QQ_LoginAction {
- const GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";
- const GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token";
- const GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me";
- private $APIMap = array(
- "get_user_info" => array( //獲取使用者資料
- "https://graph.qq.com/user/get_user_info",
- array("format" => "json"),
- ),
- "add_t" => array( //釋出一條普通微博
- "https://graph.qq.com/t/add_t",
- array("format" => "json", "content","#clientip","#longitude","#latitude","#compatibleflag"),
- "POST"
- ),
- "add_pic_t" => array( //釋出一條圖片微博
- "https://graph.qq.com/t/add_pic_t",
- array("content", "pic", "format" => "json", "#clientip", "#longitude", "#latitude", "#syncflag", "#compatiblefalg"),
- "POST"
- ),
- "del_t" => array( //刪除一條微博
- "https://graph.qq.com/t/del_t",
- array("id", "format" => "json"),
- "POST"
- ),
- "get_repost_list" => array( //獲取單條微博的轉發或點評列表
- "https://graph.qq.com/t/get_repost_list",
- array("flag", "rootid", "pageflag", "pagetime", "reqnum", "twitterid", "format" => "json")
- ),
- "get_info" => array( //獲取當前使用者資料
- "https://graph.qq.com/user/get_info",
- array("format" => "json")
- ),
- "get_other_info" => array( //獲取其他使用者資料
- "https://graph.qq.com/user/get_other_info",
- array("format" => "json", "#name-1", "#fopenid-1")
- ),
- "get_fanslist" => array(
- "https://graph.qq.com/relation/get_fanslist", //我的微博粉絲列表
- array("format" => "json", "reqnum", "startindex", "#mode", "#install", "#sex")
- ),
- "get_idollist" => array(
- "https://graph.qq.com/relation/get_idollist", //我的微博收聽列表
- array("format" => "json", "reqnum", "startindex", "#mode", "#install")
- ),
- "add_idol" => array(
- "https://graph.qq.com/relation/add_idol", //微博收聽某使用者
- array("format" => "json", "#name-1", "#fopenids-1"),
- "POST"
- ),
- "del_idol" => array( //微博取消收聽某使用者
- "https://graph.qq.com/relation/del_idol",
- array("format" => "json", "#name-1", "#fopenid-1"),
- "POST"
- )
- );
- private $keysArr;
- function __construct(){
- if($_SESSION["openid"]){
- $this->keysArr = array(
- "oauth_consumer_key" => APPID,
- "access_token" => $_SESSION['access_token'],
- "openid" => $_SESSION["openid"]
- );
- }else{
- $this->keysArr = array(
- "oauth_consumer_key" => APPID
- );
- }
- }
- public function qq_login(){
- //-------生成唯一隨機串防CSRF攻擊
- $_SESSION['state'] = md5(uniqid(rand(), TRUE));
- $keysArr = array(
- "response_type" => "code",
- "client_id" => APPID,
- "redirect_uri" => CALLBACK,
- "state" => $_SESSION['state'],
- "scope" => SCOPE
- );
- $login_url = self::GET_AUTH_CODE_URL.'?'.http_build_query($keysArr);
- header("Location:$login_url");
- }
- public function qq_callback(){
- //--------驗證state防止CSRF攻擊
- if($_GET['state'] != $_SESSION['state']){
- return false;
- }
- //-------請求引數列表
- $keysArr = array(
- "grant_type" => "authorization_code",
- "client_id" => APPID,
- "redirect_uri" => CALLBACK,
- "client_secret" => APPKEY,
- "code" => $_GET['code']
- );
- //------構造請求access_token的url
- $token_url = self::GET_ACCESS_TOKEN_URL.'?'.http_build_query($keysArr);
- $response = $this->get_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)){
- $this->showError($msg->error, $msg->error_description);
- }
- }
- $params = array();
- parse_str($response, $params);
- $_SESSION["access_token"]=$params["access_token"];
- $this->keysArr['access_token']=$params['access_token'];
- return $params["access_token"];
- }
- public function get_contents($url){
- if (ini_get("allow_url_fopen") == "1") {
- $response = file_get_contents($url);
- }else{
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
- curl_setopt($ch, CURLOPT_URL, $url);
- $response = curl_exec($ch);
- curl_close($ch);
- }
- if(empty($response)){
- return false;
- }
- return $response;
- }
- public function get_openid(){
- //-------請求引數列表
- $keysArr = array(
- "access_token" => $_SESSION["access_token"]
- );
- $graph_url = self::GET_OPENID_URL.'?'.http_build_query($keysArr);
- $response = $this->get_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)){
- $this->showError($user->error, $user->error_description);
- }
- //------記錄openid
- $_SESSION['openid']=$user->openid;
- $this->keysArr['openid']=$user->openid;
- return $user->openid;
- }
- /**
- * showError
- * 顯示錯誤資訊
- * @param int $code 錯誤程式碼
- * @param string $description 描述資訊(可選)
- */
- public function showError($code, $description = '$'){
- echo "<meta charset=\"UTF-8\">";
- echo "<h3>error:</h3>$code";
- echo "<h3>msg :</h3>$description";
- exit();
- }
- /**
- * _call
- * 魔術方法,做api呼叫轉發
- * @param string $name 呼叫的方法名稱
- * @param array $arg 引數列表陣列
- * @since 5.0
- * @return array 返加呼叫結果陣列
- */
- public function __call($name,$arg){
- //如果APIMap不存在相應的api
- if(empty($this->APIMap[$name])){
- $this->showError("api呼叫名稱錯誤","不存在的API: <span style='color:red;'>$name</span>");
- }
- //從APIMap獲取api相應引數
- $baseUrl = $this->APIMap[$name][0];
- $argsList = $this->APIMap[$name][1];
- $method = isset($this->APIMap[$name][2]) ? $this->APIMap[$name][2] : "GET";
- if(empty($arg)){
- $arg[0] = null;
- }
- $responseArr = json_decode($this->_applyAPI($arg[0], $argsList, $baseUrl, $method),true);
- //檢查返回ret判斷api是否成功呼叫
- if($responseArr['ret'] == 0){
- return $responseArr;
- }else{
- $this->showError($responseArr['ret'], $responseArr['msg']);
- }
- }
- //呼叫相應api
- private function _applyAPI($arr, $argsList, $baseUrl, $method){
- $pre = "#";
- $keysArr = $this->keysArr;
- $optionArgList = array();//一些多項選填引數必選一的情形
- foreach($argsList as $key => $val){
- $tmpKey = $key;
- $tmpVal = $val;
- if(!is_string($key)){
- $tmpKey = $val;
- if(strpos($val,$pre) === 0){
- $tmpVal = $pre;
- $tmpKey = substr($tmpKey,1);
- if(preg_match("/-(\d$)/", $tmpKey, $res)){
- $tmpKey = str_replace($res[0], "", $tmpKey);
- $optionArgList[]= $tmpKey;
- }
- }else{
- $tmpVal = null;
- }
- }
- //-----如果沒有設定相應的引數
- if(!isset($arr[$tmpKey]) || $arr[$tmpKey] === ""){
- if($tmpVal == $pre){
- continue;
- }else if($tmpVal){//則使用預設的值
- $arr[$tmpKey] = $tmpVal;
- }else{
- $this->showError("api呼叫引數錯誤","未傳入引數$tmpKey");
- }
- }
- $keysArr[$tmpKey] = $arr[$tmpKey];
- }
- //檢查選填引數必填一的情形
- if(count($optionArgList)!=0){
- $n = 0;
- foreach($optionArgList as $val){
- if(in_array($val, array_keys($keysArr))){
- $n++;
- }
- }
- if(!$n){
- $str = implode(",",$optionArgList);
- $this->showError("api呼叫引數錯誤",$str."必填一個");
- }
- }
- if($method == "POST"){
- $response = $this->post($baseUrl, $keysArr, 0);
- }else if($method == "GET"){
- $baseUrl=$baseUrl.'?'.http_build_query($keysArr);
- $response = $this->get_contents($baseUrl);
- }
- return $response;
- }
- public function post($url, $keysArr, $flag = 0){
- $ch = curl_init();
- if(! $flag) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
- curl_setopt($ch, CURLOPT_POST, TRUE);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $keysArr);
- curl_setopt($ch, CURLOPT_URL, $url);
- $ret = curl_exec($ch);
- curl_close($ch);
- return $ret;
- }
- }
相關文章
- 基於 QQ 第三方登入2019-01-12
- Java實現QQ第三方登入2020-02-01Java
- laravel實現第三方qq一鍵登入2018-07-27Laravel
- QQ第三方登入認證流程(乾貨)2020-09-25
- 簡單實現第三方qq登入和分享2018-12-07
- 【求助】不安裝手機QQ可以使用QQ登入APP嗎2019-07-27APP
- 【網頁登入】QQ 登入、微信登入、微博登入、GitHub 登入2019-10-29網頁Github
- Java QQ授權第三方登陸2019-01-20Java
- 如何用python登入qq2021-09-11Python
- 封裝QQ、微信、微博的第三方登入和分享2019-03-04封裝
- 蘋果稽核被拒——第三方QQ登入的五種情形2018-08-03蘋果
- 網站 asp.net c# 接入QQ第三方登入的方法2019-05-11網站ASP.NETC#
- [API 寫法] QQ 登入、微信登入、Facebook、google、蘋果登入2020-02-06APIGo蘋果
- 關於QQ授權登入2018-03-27
- 原生 PHP 實現支付寶 App 第三方登入獲取 使用者資訊2019-06-20PHPAPP
- QQ信任登入(PC端 )申請2020-12-22
- QQ使用者登陸介面2018-09-08
- 第三方登入原理2024-09-01
- 關於QQ郵箱登入提示一鍵登入解決方案2019-02-12
- 社會化登入分享-QQ SDK接入2019-03-04
- QQ模擬登入實現後篇2020-08-19
- windows 安裝 企業QQ後,個人qq無法登入2018-11-01Windows
- 聊聊“密碼登入”、“手機快捷登入”和“第三方聯合登入”2018-09-11密碼
- QQ 快速登入協議分析與實現2019-09-14協議
- [外掛擴充套件]qq登入外掛2019-05-11套件
- Python自動登入QQ的實現示例2020-11-23Python
- Laravel5.6 實現第三方登入 微信登入2018-07-27Laravel
- Android 第三方登入之新浪微博授權登入2018-09-13Android
- 第三方登陸:微信掃碼登入2023-02-07
- win10登入qq就卡住怎麼回事 win10電腦一登入qq就卡死如何處理2020-12-03Win10
- 使用Python編寫一個QQ辦公版的圖形登入介面!2020-09-26Python
- win10 如何檢視電腦登入過什麼qq_win10怎麼檢視qq登入記錄2020-07-25Win10
- OctoberCMS 外掛 第三方登入2021-04-14
- Android探索與鞏固(微信QQ第三方登陸填坑)2019-02-22Android
- QQ快速登入協議分析以及風險反思2020-04-05協議
- App 第三方登入獲取使用者資訊 支付寶登入後端程式碼參考2019-06-20APP後端
- GitHub OAuth 第三方登入示例教程2019-04-21GithubOAuth
- Laravel 第三方登入之微博2019-03-05Laravel