首頁 >php框架 >ThinkPHP >ThinkPHP接入QQ互聯實現登入的案例分析

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

angryTom
angryTom轉載
2020-03-05 11:35:343337瀏覽

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

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

ThinkPHP接入QQ連結實作登入的案例分析

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

(推薦教學:thinkphp教學

第一步、下載QQ互聯SDK,我們是基於thinkphp5框架下的,當然要用PHP版的SDK,下載下來後的檔案目錄如下。

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->urlUtils = new URL();
        // $this->error = new ErrorCase();
    }
    public function qq_login(){
        // $appid = $this->recorder->readInc("appid");
        // $callback = $this->recorder->readInc("callback");
        // $scope = $this->recorder->readInc("scope");
        $appid = $this->appid;
        $callback = $this->callback;
        $scope = $this->scope;
        //-------生成唯一随机串防CSRF攻击
        $state = md5(uniqid(rand(), TRUE));
        // $this->recorder->write(&#39;state&#39;,$state);
        session(&#39;state&#39;,$state);
        //-------构造请求参数列表
        $keysArr = array(
            "response_type" => "code",
            "client_id" => $appid,
            "redirect_uri" => $callback,
            "state" => $state,
            "scope" => $scope
        );
        $login_url =  $this->urlUtils->combineURL(self::GET_AUTH_CODE_URL, $keysArr);
        return $login_url;
    }
    public function qq_callback(){
        // $state = $this->recorder->read("state");
        //--------验证state防止CSRF攻击
        if(input(&#39;state&#39;) != session(&#39;state&#39;)){
            // $this->error->showError("30001");
            exit(&#39;30001&#39;);
        }
        //-------请求参数列表
        $keysArr = array(
            "grant_type" => "authorization_code",
            "client_id" => $this->appid,
            "redirect_uri" => urlencode($this->callback),
            "client_secret" => $this->appkey,
            "code" => $_GET[&#39;code&#39;]
        );
        //------构造请求access_token的url
        $token_url = $this->urlUtils->combineURL(self::GET_ACCESS_TOKEN_URL, $keysArr);
        $response = $this->urlUtils->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->error->showError($msg->error, $msg->error_description);
            // }
        }
        $params = array();
        parse_str($response, $params);
        // $this->recorder->write("access_token", $params["access_token"]);
        // return $params["access_token"];
        session(&#39;access_token&#39;,$params["access_token"]);
    }
}

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

use qqlogin\QC;
// 处理qq登录
    public function qqlogin(){
        $qq = new QC();
        $url = $qq->qq_login();
        $this->redirect($url);
    }
    // qq登录回调函数
    public function qqcallback(){
        $qq = new QC();
        $qq->qq_callback();
        $qq->get_openid();
        $qq = new QC();
        $datas = $qq->get_user_info();
        die(var_dump($datas));//为用户数据
    }

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

更多Thinkphp教學,請追蹤PHP中文網

以上是ThinkPHP接入QQ互聯實現登入的案例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:www.100txy.com。如有侵權,請聯絡admin@php.cn刪除