Facebook PHP SDK v5 getAccessToken()函数如何工作

时间:2017-08-03 21:05:26

标签: php facebook facebook-graph-api facebook-php-sdk

我正在开展一个项目,我想使用Facebook PHP SDK v5将数据发布到Facebook页面,但是我无法对我的Facebook脚本进行ajax调用。

这是我的facebook.php文件:

 <?php
 session_start();
 echo facebook();

 function facebook(){
    include_once $_SERVER['DOCUMENT_ROOT']."/Facebook/autoload.php";
    $permissions = ['manage_pages', 'publish_pages'];
    $callback = "https://www.my-domain.com/my-callback-url.php?fb=redirect";

    $fb = new Facebook\Facebook([
      'app_id' => 'xxxxxxxxxxx',
      'app_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
      'default_graph_version' => 'v2.10',
      ]);

    $helper = $fb->getRedirectLoginHelper();

    try {
        if (isset($_SESSION['facebook_access_token'])) {
            $accessToken = $_SESSION['facebook_access_token'];
        } else {
            $accessToken = $helper->getAccessToken();
        }
    } catch(Facebook\Exceptions\FacebookResponseException $e) {
        $res['error'] = 'Error: Graph returned a session error: ' . $e->getMessage();
        return json_encode($res);
    } catch(Facebook\Exceptions\FacebookSDKException $e) {
        $res['error'] = 'Error: Facebook SDK returned a session error: ' . $e->getMessage();
        return json_encode($res);
    }

    if (!isset($accessToken)) {
        $redirectUrl = $helper->getLoginUrl($callback, $permissions);
        $res['login'] =  $redirectUrl;
        return json_encode($res);
    }else{
        // rest on the script to post to a page
    }
}
?>

这是my-callback-url.php以及对facebook.php文件进行ajax调用的页面

<?php

if(isset($_GET['fb'])){
    $code = $_GET['code'];
}else{
    $code = '';
}

<script type="text/javascript">
jQuery(document).ready(function($) {

var code = "<?php echo $code; ?>";

if(code !== ''){
    postToFB(code);
}

$('#postButton').on('click',function(){
    postToFB(code);
}

function postToFB(code){
    $.ajax({
        type: "POST",
        url: 'facebook.php',
        data: {"somePostData": "someValue", "redirectCode":code},
        success: function (data) {
            var json = $.parseJSON(data);
            if(json.hasOwnProperty('login')){
                window.location.replace(json.login);
            }
        }
    });
}

});
</script>

?>

根据Facebook网站上的文件,这就是Facebook说getAccessToken()的工作方式

  

尝试从授权代码中获取访问令牌。此方法将向Graph API发出请求并返回响应。如果该进程中存在错误,则将抛出FacebookSDKException。如果CSRF验证失败,也会抛出FacebookSDKException。

我遇到的问题是当我的用户访问my-callback-url.php并点击#postButton时,该脚本会对facebook.php进行ajax调用

如果facebook.php无法获取访问令牌,则会调用:

 $redirect = $helper->getLoginUrl($callback, $permissions);

这会将$redirect值发送回my-callback-url.php中的ajax函数,而success方法会将用户发送到该重定向网址。

用户进行身份验证后,Facebook会将用户重新发送回my-callback-url.php完整的网址回调,如下所示:

 https://www.my-domain.com/my-callback-url.php&fb=redirect?code=xxxxxxxxxx?state=xxxxxxxxxx

在回调完成后,my-callback-url.php再次运行ajax脚本以及从回调中获取的代码参数。我的问题是如何将回调中获得的代码参数传递给getAccessToken()内的facebook.php函数?

getAccessToken()似乎不接受代码参数。我想知道是否需要将代码参数设置为特定的会话变量,以便getAccessToken()读取它。有谁知道如何使这项工作?

1 个答案:

答案 0 :(得分:2)

您无需对login-redirect URL中的code参数执行任何操作。

getAccessToken()方法使用类getCode()方法获取代码本身,该方法从URL查询字符串中提取代码。所以,一旦你回到my-callback-url.php,你可以调用该方法,它应该返回访问令牌。

这可以从SDK中的方法本身看出:

/**
 * Takes a valid code from a login redirect, and returns an AccessToken entity.
 *
 * @param string|null $redirectUrl The redirect URL.
 *
 * @return AccessToken|null
 *
 * @throws FacebookSDKException
 */
public function getAccessToken($redirectUrl = null)
{
    if (!$code = $this->getCode()) {
        return null;
    }

    $this->validateCsrf();
    $this->resetCsrf();

    $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl();
    // At minimum we need to remove the state param
    $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['state']);

    return $this->oAuth2Client->getAccessTokenFromCode($code, $redirectUrl);
}

只需提醒一句:不要多次调用getAccessToken() - 进行一次调用并将结果存储在变量中。使用相同代码的任何后续调用都将被视为跨站点请求伪造,并且将抛出异常。