• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • PHP第三方登錄學習筆記

    標簽: php

    一、OAuth2.0

    (一)什么是OAuth

    全稱為Open Authorization,即開放式授權。
    OAuth協議為用戶資源的授權提供了一個安全的、開放而又簡易的標準。與以往的授權方式不同之處是OAuth的授權不會使第三方觸及到用戶的賬戶信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權,因此OAuth是安全的。

    (二)OAuth的工作原理

    這里寫圖片描述

    (三)OAuth的應用場景

    • QQ用戶授權慕課網使用其QQ賬號相關的信息
    • 獲取授權后,在符合權限規則的情況下訪問各種API

    (四)三個重要步驟

    步驟一:請求OAuth登錄頁
    Request Token URL:未授權的令牌請求服務地址
    (帶有特定參數的URL,如AppID、AppKey、回調地址)
    步驟二:用戶使用第三方賬號登錄并授權
    第三方賬號登錄成功后,會跳轉到指定的回調地址,并帶上一個GET參數code,這個code是會過期的,有效期非常短,并且只可以使用一次。
    步驟三:返回登錄結果
    User Authorization URL:用戶授權的令牌請求服務地址
    用戶QQ登錄授權之后需要請求一個帶有特定參數的URL(此時用戶已授權)
    這里寫圖片描述
    請求驗證通過之后會得到一個響應數據,從這個相應數據可以知道這個用戶的昵稱、頭像等基本賬號信息。

    (五)關于AccessToken

    AccessToken:用戶通過第三方應用訪問OAuth接口的令牌
    相應數據里面包含AccessToken,有了它,第三方站點就可以以用戶的身份執行OAuth服務方允許執行的操作,如:分享QQ空間。

    (六)AccessToken和Refresh Token

    1、數據傳輸原理

    訪問開放平臺的接口實質上都是通過第三方應用拼接一個特定的URL來訪問API的。即使是連續幾次訪問同一個API接口,動態拼接的URL也有可能是不一樣的,即任意一次訪問一個API都需要重新拼接一個URL,而且每次都需要用上AccessToken。出于安全考慮,一般都是使用POST發起HTTP請求。開放平臺再將數據打包成xml/json返回。
    這里寫圖片描述

    2、生命周期解析

    AccessToken有生命周期,較長(10天半個月甚至更長)。
    如果AccessToken過期了,
    (1)重新授權登錄第三方站點
    (2)User Authorization URL中指定參數need_refresh_token=true(不同開放平臺叫法不一樣)指明返回時攜帶Refresh Token參數。當AccessToken快過期時,就可以使用Refresh Token動態拼接URL請求獲得一個新的AccessToken。
    Refresh Token也有生命周期,更長(幾個月半年甚至更長)。

    二、第三方登錄——QQ登錄

    (一)前置條件

    • 一個QQ號
    • 一臺公網通過域名可訪問的web服務器(沒有域名無法申請到AppID)
    • 關于備案
      下面表格0表示免備案,1表示必須備案:
    服務器 \ 用途 開發練手 發布上線
    中國大陸 騰訊=0 0 | 1 = 1 騰訊=1 1 | 1 = 1
    工信部=1 工信部=1
    港澳臺及國外 騰訊=0 0 | 0 =0 騰訊=1 1 | 0 =1
    工信部=0 工信部=0

    (二)申請AppID和AppKey

    QQ互聯:https://connect.qq.com/
    登錄,點擊應用管理,填寫資料,郵箱驗證,完成注冊。完成之后就可以進去創建應用了。
    創建過程中注意驗證步驟:
    這里寫圖片描述

    (三)引入官方SDK

    SDK是官方提供的接入QQ登錄的示例代碼。
    SDK下載:http://wiki.connect.qq.com/sdk%E4%B8%8B%E8%BD%BD
    SDK參數配置:訪問SDK的install目錄,根據要求填寫表單。
    請求授權列表中:get_user_info是獲取用戶基本信息
    勾選的權限會在登錄頁面中展示:
    這里寫圖片描述
    配置成功之后,只保留API目錄即可。

    (四)SDK解讀

    文檔資料:http://wiki.connect.qq.com/
    這里寫圖片描述
    SDK核心類和重要方法
    1、登錄授權相關的三個主要類(API/class/*.class.php)
    Recorder.class.php:配置讀取與SESSION存取
    URL.class.php:基于CURL庫的get與post請求
    Oauth.class.php:Oauth相關URL動態拼接與token操作
    Recorder.class.php:

    • __construct()
    $incFileContents = file(ROOT."comm/inc.php");//讀入配置文件
    $incFileContents = $incFileContents[1];
    $this->inc = json_decode($incFileContents);//解析成php對象
    • readInc($name)
    return $this->inc->$name;
    //->readInc('appid')即讀取配置文件的appid

    URL.class.php:

    • combineURL(baseURL,keysArr)
    $combined = $baseURL."?";//拼接?
    foreach($keysArr as $key => $val){
       $valueArr[] = "$key=$val";//拼接參數
    }
    $keyStr = implode("&",$valueArr);//使用&拼接參數鍵值對
    • get(url,keysArr) 發送get請求
    • post(url,keysArr, $flag = 0) 發送post請求

    Oauth.class.php:

    • qq_login() 拼接QQ登錄頁面URL
    $appid = $this->recorder->readInc("appid");//讀取appid
    $callback = $this->recorder->readInc("callback");//讀取回調地
    $scope = $this->recorder->readInc("scope");//讀取授權列表
    
    //-------生成唯一隨機串防CSRF攻擊
    $state = md5(uniqid(rand(), TRUE));//原樣返回參數
    $this->recorder->write('state',$state);//state寫入session中
    
    //-------構造請求參數列表
    $keysArr = array(
        "response_type" => "code",
        "client_id" => $appid,
        "redirect_uri" => $callback,
        "state" => $state,
        "scope" => $scope
    );
    
    //拼接URL之后
    $login_url =  $this->urlUtils->combineURL(self::GET_AUTH_CODE_URL, $keysArr);
    header("Location:$login_url");//跳轉到生成的url
    • qq_callback() QQ登錄完成后的回調處理
    $state = $this->recorder->read("state");
    
    //--------驗證state防止CSRF攻擊
    if(!$state || $_GET['state'] != $state){//返回的state和本地的不一致拋出錯誤提示
        $this->error->showError("30001");
    }
    
    //State參數是可選的
    //為數據傳輸再添加一道安全保障
    
    //-------請求參數列表
    $keysArr = array(
        "grant_type" => "authorization_code",
        "client_id" => $this->recorder->readInc("appid"),
        "redirect_uri" => urlencode($this->recorder->readInc("callback")),
        "client_secret" => $this->recorder->readInc("appkey"),
        "code" => $_GET['code']
    );
    
    //------構造請求access_token的url
    $token_url = $this->urlUtils->combineURL(self::GET_ACCESS_TOKEN_URL, $keysArr);
    $response = $this->urlUtils->get_contents($token_url);

    (五)SDK優化

    • 調整文件及目錄結構
    • SDK中的常量名太常見可能和現有項目沖突,批量替換SDK中的常量名稱為不常見名稱

    (六)開發

    首頁index.php:

    <?php
    require_once 'Connect2.1/qqConnectAPI.php';
    ?>
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <?php if (!isset($_COOKIE['qq_accesstoken']) && !isset($_COOKIE['qq_openid'])){ ?>
        <a href="qqlogin.php">QQ登錄</a>
        <?php }else{ ?>
        <a href="qqlogout.php">退出QQ</a>
        <?php
            $qc=new QC($_COOKIE['qq_accesstoken'],$_COOKIE['qq_openid']);
            $userinfo=$qc->get_user_info();
            var_dump($userinfo);
        } ?>
    </body>
    </html>

    申請上線需要使用官網提供的QQ登錄按鈕素材。
    QQ登錄頁面qqlogin.php:

    require_once 'Connect2.1/qqConnectAPI.php';
    
    //訪問QQ登錄頁面
    $oauth=new Oauth();
    $oauth->qq_login();

    回調地址頁面callback.php:

    require_once 'Connect2.1/qqConnectAPI.php';
    
    //請求access token
    $oauth=new Oauth();
    $accessToken=$oauth->qq_callback();
    //獲取openID
    //QQ用戶在第三方站點的唯一標識
    //同一個QQ用戶在不同站點使用QQ登錄openID始終一樣
    $openID=$oauth->get_openid();
    
    setcookie('qq_accesstoken',$accessToken,time()+86400);//時間要比access token的有效期短
    setcookie('qq_openid',$openID,time()+86400);
    
    header('Location: index.php');

    退出頁面qqlogout.php:

    setcookie('qq_accesstoken',null);
    setcookie('qq_openid',null);
    版權聲明:本文為xx_xxxxxxxxxx1120原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/xx_xxxxxxxxxx1120/article/details/81152791

    智能推薦

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    猜你喜歡

    統計學習方法 - 樸素貝葉斯

    引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...

    styled-components —— React 中的 CSS 最佳實踐

    https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...

    基于TCP/IP的網絡聊天室用Java來實現

    基于TCP/IP的網絡聊天室實現 開發工具:eclipse 開發環境:jdk1.8 發送端 接收端 工具類 運行截圖...

    19.vue中封裝echarts組件

    19.vue中封裝echarts組件 1.效果圖 2.echarts組件 3.使用組件 按照組件格式整理好數據格式 傳入組件 home.vue 4.接口返回數據格式...

    劍指Offer39-調整數組順序使奇數位于偶數前面

    一開始想著用冒泡排序的方法來做,但是bug還是很多,后來看了評論區答案,發現直接空間換時間是最簡單的,而且和快排的寫法是類似的。...

    精品国产乱码久久久久久蜜桃不卡