2016-08-18 109 views
1

我知道這個問題是另一個問題的重複,但是在搜索Google和Stack Overflow之後,我仍然沒有找到解決方案。Facebook API - 永久數據中缺少必需的參數「狀態」

我有一些調用Facebook API的登錄URL的代碼。但是,我以一種間接的方式來做這件事。基本上這裏是服務器流量:

  1. 客戶選擇登錄與FB到App
  2. 客戶網站(A)發送HTTP GET請求到中間網站(B)
  3. 網站B返回登錄URL B關於網站它包括2個回調:到FB與FB-> getLoginUrl(生成的登錄URL)和回調網站A.
  4. 網站甲重定向到登錄在其重定向到登錄頁面上FB
  5. 用戶登錄網站B頁並授權FB網站上的應用程序
  6. FB重定向到獲取訪問碼的網站B上的回調。作爲$ _GET變量
  7. 網站上使用訪問令牌,因爲它希望

所以很複雜,我只包括流可能使回答

  • 網站B重定向到網站的回調傳遞接入碼這個問題和理解PHP中的代碼更容易。

    PHP 網站代碼:

    if (!isset($_GET['code'])) { 
        $callback = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; 
        $request_url = "http://embocorp.com/factory/api.php/facebook/login?callback=".$callback; 
        header("Location: ".implode(json_decode(callAPI("GET", $request_url), true)['body']['data'])); 
    } else { 
        echo $_GET['code']; 
    } 
    

    網站B代碼: api.php

    if (!session_id()) { 
        session_start(); 
    } 
    
    require_once("vendor/autoload.php"); 
    
    $method = $_SERVER['REQUEST_METHOD']; 
    $request = explode('/', trim($_SERVER['PATH_INFO'],'/')); 
    $input = $_SERVER['PATH_INFO']; 
    $table = array_shift($request); 
    $key = array_shift($request); 
    parse_str($_SERVER['QUERY_STRING'], $query_array); 
    
    $callback = "http://embocorp.com/factory/api.php/facebook/callback?call="; 
    
    function returnData($data, $options = "") {  
        $response = [ 
        "data"=>$data 
        ]; 
        return json_encode($response, $options); 
    } 
    function getFacebookConnection($appid, $appsecret) { 
        return new Facebook\Facebook(['app_id' => $appid,'app_secret' => $appsecret,'default_graph_version' => 'v2.5', 'persistent_data_handler'=>'session']); 
    } 
    function facebookHandleRequest($request, $connection, $details = null) { 
        switch($request) { 
        case "login": 
         $callback_url = $GLOBALS["callback"].$GLOBALS['query_array']['callback']; 
         echo returnData("http://embocorp.com/factory/login.php?fb=".getFacebookLoginURL($connection, $callback_url), JSON_UNESCAPED_SLASHES); 
         break; 
        case "callback": 
         if (!empty($GLOBALS["query_array"])) { 
         foreach ($_COOKIE as $k=>$v) { 
          if(strpos($k, "FBRLH_")!==FALSE) { 
          $_SESSION[$k]=$v; 
          } 
         } 
         $access = getFacebookAccessCode($connection); 
         $called = $GLOBALS['query_array']['called']; 
         header("location: ".$called."?code=".$access); 
         } else { 
         echo returnError(400, "Bad Request, missing authorization"); 
         } 
         break; 
        case "me": 
         if (!empty($GLOBALS["query_array"]) && array_key_exists("accessToken", $GLOBALS["query_array"]) == true) { 
         $response = $connection->sendRequest('GET', '/me', [], $GLOBALS["query_array"]["accessToken"], 'eTag', 'v2.2'); 
         $user = $response->getGraphUser(); 
         echo returnData($user); 
         } else { 
         echo returnError(400, "Bad Request, missing authorization"); 
         } 
         break; 
        default: 
         echo returnError(404, "Request URI Not Found"); 
         break; 
        } 
    } 
    function getFacebookLoginURL($connection, $callback_url) { 
        $helper = $connection->getRedirectLoginHelper(); 
        $permissions = ['manage_pages', 'publish_pages', 'read_insights']; 
        $loginUrl = $helper->getLoginUrl($callback_url, $permissions); 
        foreach ($_SESSION as $k=>$v) {      
        if(strpos($k, "FBRLH_")!==FALSE) { 
         if(setcookie($k, $v)) { 
         $_COOKIE[$k]=$v; 
         } 
        } 
        } 
        return $loginUrl; 
    } 
    function getFacebookAccessCode($fb){ 
        if (!session_id()) { 
        $accessToken = $_SESSION['facebook_access_token']; 
        return $accessToken; 
        } else { 
        $helper = $fb->getRedirectLoginHelper(); 
        try { 
         $accessToken = $helper->getAccessToken(); 
        } catch(Facebook\Exceptions\FacebookResponseException $e) { 
         echo 'Graph returned an error: ' . $e->getMessage(); 
         exit; 
        } catch(Facebook\Exceptions\FacebookSDKException $e) { 
         echo 'Facebook SDK returned an error: ' . $e->getMessage(); 
         exit; 
        } 
        if (isset($accessToken)) { 
         $_SESSION['facebook_access_token'] = (string) $accessToken; 
         return (string) $accessToken; 
        } else { 
         return false; 
        } 
        } 
    } 
    
    switch ($table) { 
        case "facebook": 
        $fb = getFacebookConnection($appid, $appsecret); 
        facebookHandleRequest($key, $fb); 
        break; 
        case "twitter": 
        echo "no"; 
        break; 
        default: 
        exit(); 
        break; 
    } 
    
    session_write_close(); 
    
    ?> 
    

    的login.php

    if (!session_id()) { 
        session_start(); 
    } 
    if (isset($_GET['fb'])) { 
        $redirect = str_replace("fb=", "", $_SERVER['QUERY_STRING']); 
        header("Location: ".$redirect); 
    } else { 
        echo "ni"; 
    } 
    

    再次感謝您的幫助,這已經讓我瘋狂了72小時。

  • +0

    你在哪裏執行交換訪問令牌代碼的步驟?由於您在域B下創建了登錄URL,因此您必須在B上執行此操作,因爲狀態值存儲在域B的會話中。 – CBroe

    +0

    我在域B上執行它。Login.php轉到facebook,然後轉到返回api.php交換訪問令牌的代碼。 –

    +0

    然後檢查您的會話(在B上)是否正常工作 - 您是否在前後獲得相同的會話ID? – CBroe

    回答

    -1

    只需添加,

    if (!session_id()) { 
        session_start(); 
    } 
    
    在開始

    兩個文件。

    +0

    一般而言,如果答案包含對代碼意圖做什麼的解釋,以及爲什麼解決問題而不引入其他問題,則答案會更有幫助。 – Peter

    +0

    @Peter對不起, 這裏是我如何找到我的解決方案, [from this disccusion](https://github.com/facebook/php-graph-sdk/issues/473) 我發現facebook- php-graph-sdk正在使用會話。我嘗試了session_start(),這是工作 –

    相關問題