2016-08-18 89 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(),这是工作 –

    相关问题