如何识别来自Facebook的回调

时间:2015-12-07 16:36:46

标签: php facebook facebook-graph-api

对于PHP PHP API / SDK存在问题,让我首先描述: 我建立了一个网站,你可以在其中输入'引号'(短信),然后在网站上保存报价(阅读;它背后的mysql数据库)你可以决定与Facebook分享报价,以便能够赢得东西。

流程(它应该如何工作)是这样的:

  1. 用户打开我的网站,PHP从Facebook PHP API / SDK
  2. 获取登录URL
  3. PHP阅读&记忆上述步骤中登录网址中的“州”网址变量(多个网站提到这将是识别用户的有效方式)
  4. 用户保存报价,我将状态变量从上面存储在该报价的db记录中,以便我稍后再次使用它来匹配返回的用户和​​保存的报价。
  5. 用户决定想要获胜,因此他/她点击了Facebook分享按钮,该按钮将其浏览器指向第1步的Facebook登录网址
  6. 用户的浏览器现在正在查看一些Facebook页面,他们必须允许访问该应用并允许它发布到他们的墙上
  7. 一旦用户提供了访问权限,他们就会返回我网站的回调网址(这恰好与第4步中的“原始网址”相同)
  8. 我网站上的PHP在返回的url变量(?)中找到状态变量,通过数据库查找匹配的引用记录,如果找到,它会存储一些Facebook用户数据(userid和avatar的路径)相关的数据库记录。
  9. PHP继续将之前保存的报价发布到用户的Facebook墙上。
  10. 从本质上讲,事情是有效的,但最重要的一点,第7步,确定谁通过状态变量回来,却没有。问题是我只是得到了一些冗长的'代码'GET变量,而不是'状态'GET变量,并且在API文档或StackOverflow或Google上没有任何地方我找到了如何更改它以便我得到'州'GET变量再次返回......?

    所以回顾一下,基本上我正在寻找的是能够向Facebook发送某种标识符,然后将其包含在callback-url中,据我所知,这就是'state'变量最适合的,如果它会起作用。

    我正在使用当前最新的API(今天早上的facebook-php-sdk-v4-5.0.0.zip)下面我分享了我用来与Facebook PHP API / SDK交互的所有相关代码,所有此代码驻留在我的网站的public_html目录中的index.php中,我的应用程序的回调网址与index.php相同 这段代码是从几个例子拼凑而成的,基本上可以工作,我只是没有得到所需的状态变量。

    require_once __DIR__ . '<PATH-TOO-FB-API>/src/Facebook/autoload.php';
    session_start();
    
    $fbStateCode = ""; // used to memorize state code
    $fbLoginUrl = ""; // user to memorize login url
    
    // Init the API
    // If you go end up testing this, dont forget too change <APP-ID> & <APP-SECRET>
    $fb = new Facebook\Facebook([
        'app_id' => '<APP-ID>',
        'app_secret' => '<APP-SECRET>',
        'default_graph_version' => 'v2.4',
        'default_access_token' => isset($_SESSION['facebook_access_token']) ? $_SESSION['facebook_access_token'] : '<APP-ID>|<APP-SECRET>'
    ]);
    
    // login helper
    $helper = $fb->getRedirectLoginHelper();
    
    // try get an accesstoken (wich we only have if user returned from facebook after logging in)
    try {
        $accessToken = $helper->getAccessToken();
    } catch(Facebook\Exceptions\FacebookResponseException $e) {
        //echo 'Graph returned an error: ' . $e->getMessage(); // When Graph returns an error
    } catch(Facebook\Exceptions\FacebookSDKException $e) {
        //echo 'Facebook SDK returned an error: ' . $e->getMessage(); // When validation fails or other local issues
    }
    
    if (isset($accessToken)) {
        // User is logged in!
        try {
            // Now we look up some details about the user
            $response = $fb->get('/me?fields=id,name');
            $facebook_user = $response->getGraphUser();
            exit; //redirect, or do whatever you want
        } catch(Facebook\Exceptions\FacebookResponseException $e) {
            //echo 'Graph returned an error: ' . $e->getMessage();
        } catch(Facebook\Exceptions\FacebookSDKException $e) {
            //echo 'Facebook SDK returned an error: ' . $e->getMessage();
        }
        // if facebook_user has an id, we assume its a user and continue
        if(isset($facebook_user['id'])) {
            $avatarUrl = "http://graph.facebook.com/".$facebook_user['id']."/picture";
            // THE BELOW 8 LINES HANDLE LOADING A QUOTE FROM DB WITH MATCHING STATE AND SAVING
            // ADDITIONAL DATA TOO IT, THE ONLY ISSUE HERE IS THAT $_GET['state'] DOESNT EXIST
            // THE REST OF THIS PROCESS HAS ALREADY BEEN TESTED AND PROOFED TO BE WORKING
            $curr_quote = Quotes::getQuoteByFbStateCode($_GET['state']);
            $curr_quote_data = $curr_quote->getData();
            $curr_quote->updateData(array(
                "fb_access_token" => $accessToken,
                "fb_uid" => $facebook_user['id'],
                "fb_avatar_path" => $avatarUrl
            ));
            // Save it
            if($curr_quote->save()) { // Success! quote in db was updated
                // Now that we are logged in and have matched the returned user with a saved quote, we can post that quote too facebook
                $_SESSION['facebook_access_token'] = (string) $accessToken; // storing the access token for possible use in the FB API init
                // This is the data we post too facebook
                $msg_data = array (
                    'message' => $curr_quote_data['quote']
                );
                $response = $fb->post('/me/feed',$msg_data,$accessToken); // do the actual post (this, like everything else besides state variable, works)
            } else { // Fail! quote in db was NOT updated?!
                // handle errors
            }
        }
    } else {
        // User is NOT logged in
        // So lets build up a login url
        $permissions = ['public_profile','publish_actions']; // we want these permissions (note, atm im the only tester, so while the app still needs to be reviewed for the 'publish_actions' permission, it works cuz i own the app and test with same fb account)
        $fbLoginUrl = $helper->getLoginUrl('http://<WEBSITE-URL>/index.php', $permissions); // get the login url from the api providing callback url and permissions array
        $fbLoginUrlParams = array();
        parse_str($fbLoginUrl, $fbLoginUrlParams); // store the url params in a new array so that we can (read next comment below)
        $fbStateCode = $fbLoginUrlParams['state']; // read out and store the state url variable
    }
    

    下面是基于用户交互将新报价保存到数据库的逻辑,并利用$fbStateCode,这部分流程功能也很好,报价以他们自己的唯一状态值保存,就像他们一样应该。

    所以这就是故事,我正在尝试做一些我非常确定没有什么特别的东西,它只是记录不完整或其他什么东西?

2 个答案:

答案 0 :(得分:0)

结束重写这一批,现在它工作正常,不确定现在与我的情况有什么不同,所以无法为遇到类似问题的其他人提供一个更大的功能,对不起那个。

@Cbroe;转发了你给我的客户端的抬头,字面上告诉'不是我们的问题,但是制造这个概念的公司的问题',所以时间会告诉我这是否甚至上网哈哈,仍然,谢谢你的抬头:P

答案 1 :(得分:-1)

阅读有关state变量here的文档:

state参数是客户端在登录重定向到登录URL之前提供的值。如果它可用,那么它将在回调URL中发回。

因此,除非您在step1中提供任何状态变量,否则您将无法从FB(以及任何其他oAuth2实现API)获得任何状态变量。除了在步骤1中为其提供可行的PHP应用程序状态之外,不会出现任何“魔术”。

实际上,state参数是为了让任何客户端能够在回调“发生”时恢复上下文。因此,状态变量的内容可以是会话ID,用户ID或任何其他有助于在收到回调后再次恢复(php)应用程序上下文的值

修改

我假设,状态变量需要在此函数的某处添加:

 $helper = $fb->getRedirectLoginHelper();