ThinkPHP接入QQ互聯實現登錄的案例分析

本篇介紹了使用thinkphp接入qq互聯實現第三方登錄的方法,作為一個小案例來為各位講解,希望對各位有幫助。

ThinkPHP接入QQ互聯實現登錄的案例分析

Thinkphp接入QQ互聯實現登錄的案例分析

我的一個二級域名項目想在也想接入QQ第三方登錄功能,該項目采用的thinkphp5框架開發的項目,在網上搜了一些接入的案例,個人覺得魚龍混雜不太適合自己,現在自己重新在thinkphp5框架上開發這個功能,下面是詳細的開發步驟。

(推薦教程:thinkphp教程

第一步、下載QQ互聯SDK,我們是基于thinkphp5框架下的,當然是要用PHP版的SDK,下載下來后的文件目錄如下。

立即學習PHP免費學習筆記(深入)”;

ThinkPHP接入QQ互聯實現登錄的案例分析

第二步、將SDK主要目錄上傳到服務器合適的目錄下,先說下SDK的主要的目錄是API文件夾里面的class目錄,當初為了做配置設置項測試,我上傳了install文件夾,然后再開發環境配置了APP ID、APP Key以及callback_url,配置好之后會在API/comm文件夾中多處一個inc.php配置文件,最后再recorder類中會引用這個配置文件。可是在后面的 開發過程中我發現會報這個錯The state does not match. You may be a victim of csrf。后面我把qqlogin方法里面的 state放到Session中,對官網的DEMO SDK已經完全失去信心了,不在用QQ互聯全部的文件而是挑幾個重要的類文件來做開發。后面想想官方給的SDK只是普通的PHP代碼格式,我應用到thinkphp那很多東西都已經變了,最后我選擇上個類文件,QC.php、URL.php、Oauth.php上傳到extend/qqlogin目錄下。在thinkphp5的項目中擴展類一般上傳到extend文件夾下,如下圖所示我上次的目錄位置。

ThinkPHP接入QQ互聯實現登錄的案例分析

第三步、改造上述三個類文件,因為QC.php是繼承了Oauth.php,我們從后者改起,去掉require_once,加上命名空間Namespace qqlogin,首先看成員屬性,類常量是騰訊平臺的地址,不用管,原來有三個屬性,recorder、Error不需要,注釋掉或直接刪掉。下文同樣,因為5個類文件我們只用到3個類文件,一個是報錯類一個讀取配置相關類。下面看Oauth.php成員屬性、qqlogin跳轉方法、qqcallback回調方法的,其他兩個類文件沒有太大的改大,按照上述規則改即可

<?php /* PHP SDK  * @version 2.0.0  * @author connect@qq.com  * @copyright ? 2013, Tencent Corporation. All rights reserved.  */ namespace qqlogin; use qqlogin; class Oauth{     const VERSION = "2.0";     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";     // protected $recorder;     public $urlUtils;     // protected $error;          function __construct(){         // $this->recorder?=?new?Recorder(); ????????$this-&gt;urlUtils?=?new?URL(); ????????//?$this-&gt;error?=?new?ErrorCase(); ????} ????public?function?qq_login(){ ????????//?$appid?=?$this-&gt;recorder-&gt;readInc("appid"); ????????//?$callback?=?$this-&gt;recorder-&gt;readInc("callback"); ????????//?$scope?=?$this-&gt;recorder-&gt;readInc("scope"); ????????$appid?=?$this-&gt;appid; ????????$callback?=?$this-&gt;callback; ????????$scope?=?$this-&gt;scope; ????????//-------生成唯一隨機串防CSRF攻擊 ????????$state?=?md5(uniqid(rand(),?TRUE)); ????????//?$this-&gt;recorder-&gt;write('state',$state); ????????session('state',$state); ????????//-------構造請求參數列表 ????????$keysArr?=?array( ????????????"response_type"?=&gt;?"code", ????????????"client_id"?=&gt;?$appid, ????????????"redirect_uri"?=&gt;?$callback, ????????????"state"?=&gt;?$state, ????????????"scope"?=&gt;?$scope ????????); ????????$login_url?=??$this-&gt;urlUtils-&gt;combineURL(self::GET_AUTH_CODE_URL,?$keysArr); ????????return?$login_url; ????} ????public?function?qq_callback(){ ????????//?$state?=?$this-&gt;recorder-&gt;read("state"); ????????//--------驗證state防止CSRF攻擊 ????????if(input('state')?!=?session('state')){ ????????????//?$this-&gt;error-&gt;showError("30001"); ????????????exit('30001'); ????????} ????????//-------請求參數列表 ????????$keysArr?=?array( ????????????"grant_type"?=&gt;?"authorization_code", ????????????"client_id"?=&gt;?$this-&gt;appid, ????????????"redirect_uri"?=&gt;?urlencode($this-&gt;callback), ????????????"client_secret"?=&gt;?$this-&gt;appkey, ????????????"code"?=&gt;?$_GET['code'] ????????); ????????//------構造請求access_token的url ????????$token_url?=?$this-&gt;urlUtils-&gt;combineURL(self::GET_ACCESS_TOKEN_URL,?$keysArr); ????????$response?=?$this-&gt;urlUtils-&gt;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-&gt;error)){ ????????????//?????$this-&gt;error-&gt;showError($msg-&gt;error,?$msg-&gt;error_description); ????????????//?} ????????} ????????$params?=?array(); ????????parse_str($response,?$params); ????????//?$this-&gt;recorder-&gt;write("access_token",?$params["access_token"]); ????????//?return?$params["access_token"]; ????????session('access_token',$params["access_token"]); ????} }

第四步、編寫控制器調用函數和回調函數,同時檢查回調地址是否正確(回調地址是當你添加QQ第三方登錄QQ互聯返回跳轉的地址,該地址攜帶重要參數,能獲取最后用戶的數據),有些時候如果你在QQ互聯填寫的回調地址與你控制器的不一樣,那么最后就會卡在那個QQ互聯填寫的回調地址那,如www.100txy.com/index.php?code=65B7668A4F1BBB71DD0DF52B55AC1FC1&state=804e921e18e3545ecdf690316639c067。下面是控制器方法

use?qqloginQC; //?處理qq登錄 ????public?function?qqlogin(){ ????????$qq?=?new?QC(); ????????$url?=?$qq-&gt;qq_login(); ????????$this-&gt;redirect($url); ????} ????//?qq登錄回調函數 ????public?function?qqcallback(){ ????????$qq?=?new?QC(); ????????$qq-&gt;qq_callback(); ????????$qq-&gt;get_openid(); ????????$qq?=?new?QC(); ????????$datas?=?$qq-&gt;get_user_info(); ????????die(var_dump($datas));//為用戶數據 ????}

值得注意的是在回調函數里面要實例化兩次QC才能拿到用戶信息,第二次實例化的時候才有openid和access_token兩個參數。

更多Thinkphp教程,請關注thinkphp教程

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享