Facebook SDK访问令牌和Ajax

时间:2018-10-11 05:59:16

标签: php ajax facebook facebook-access-token facebook-sdk-3.1

我遵循了PHP文档的Facebook SDK,并创建了两个文件login.php和fb-callback.php,所有查找逻辑都在fb-callback.php中。当我这样做时,一切正常。

但是我想将查找逻辑移到get-posts.php并通过fb-callback.php通过ajax调用它。这样做时,我似乎无法获得访问令牌。我收到下面指出的错误,“访问令牌:错误的请求”。

我已经将fb-config.php和get-posts.php注册为有效的OAuth重定向URI。那么,如何获取get-posts.php的适当参数?

以下是所有相关文件:

login.php

<?php
require_once "config.php";

$redirectURL = 'https://' . $_SERVER[ 'SERVER_NAME' ] . '/r/fb-callback.php';
$permissions = ['email','user_photos','user_posts'];
$loginUrl = $helper->getLoginUrl($redirectURL, $permissions);
?>

<a href='<?php echo $loginUrl; ?>'>
<img src='continue-with-facebook.png'>
</a>
?>

config.php

<?php
if( !session_id() ) {
    session_start();
}

require_once '/home/bitnami/vendor/autoload.php';

$fb = new Facebook\Facebook([
  'app_id' => '---',
  'app_secret' => '---',
  'default_graph_version' => 'v3.1',
  ]);

$helper = $fb->getRedirectLoginHelper();
?>

fb-callback.php

<?php
require_once("config.php");
?>
<html>
<head>
  <script type='text/javascript' src='jquery.js'></script>
  <script>
    var $j = jQuery.noConflict();

    $j(document).ready(function () {

      $j.ajax({
        type: "GET",
        url: "get-posts.php",
        cache: false,
        success: function (html) {
          setTimeout(function () {
            $j('#updateDiv').html(html);
          }, 1000);
        }
      });
    });
  </script>
    </head>
    <body>
        <div id='updateDiv'><img src='spinning.gif' alt='processing...'></div> 
    </body>
</html>

get-posts.php

<?php
require_once("config.php");

// get the posts for this user id
try {
  $accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
  // When Graph returns an error
  echo __LINE__ . ' Access Token: Graph returned an error: ' . $e->getMessage();
  exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
  // When validation fails or other local issues
  echo __LINE__ . ' Access Token: Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}

if (! isset($accessToken)) {
  if ($helper->getError()) {
    header('HTTP/1.0 401 Unauthorized');
    echo "Error: " . $helper->getError() . "\n";
    echo "Error Code: " . $helper->getErrorCode() . "\n";
    echo "Error Reason: " . $helper->getErrorReason() . "\n";
    echo "Error Description: " . $helper->getErrorDescription() . "\n";
  } else {
    header('HTTP/1.0 400 Bad Request');
    echo __LINE__ . ' Access Token: Bad request';
  }
  exit;
}

...

2 个答案:

答案 0 :(得分:3)

这是实际的代码,用于解释以下内容:

fb-callback.php

<?php
require_once("config.php");

try {
  $accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
  // When Graph returns an error
  echo __LINE__ . ' Access Token: Graph returned an error: ' . $e->getMessage();
  exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
  // When validation fails or other local issues
  echo __LINE__ . ' Access Token: Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}

if (! isset($accessToken)) {
  if ($helper->getError()) {
    header('HTTP/1.0 401 Unauthorized');
    echo "Error: " . $helper->getError() . "\n";
    echo "Error Code: " . $helper->getErrorCode() . "\n";
    echo "Error Reason: " . $helper->getErrorReason() . "\n";
    echo "Error Description: " . $helper->getErrorDescription() . "\n";
  } else {
    header('HTTP/1.0 400 Bad Request');
    echo __LINE__ . ' Access Token: Bad request';
  }
  exit;
}

$get = "?accessToken=" . $accessToken;
?>
<html>
<head>
  <script type='text/javascript' src='jquery.js'></script>
  <script>
    var $j = jQuery.noConflict();

    $j(document).ready(function () {

      $j.ajax({
        type: "GET",
        url: "get-posts.php<?php echo $get; ?>",
        cache: false,
        success: function (html) {
          setTimeout(function () {
            $j('#updateDiv').html(html);
          }, 1000);
        }
      });
    });
  </script>
    </head>
    <body>
        <div id='updateDiv'><img src='spinning.gif' alt='processing...'></div> 
    </body>
</html>

get-posts.php

<?php
require_once("config.php");

$fb->setDefaultAccessToken($_GET['accessToken']);

...

那么什么改变了?首先,我需要在fb-callback.php中获取访问代码,而不是get-posts.php。因此,我将逻辑移到获取访问代码的位置,然后将错误检查回到fb-callback.php。然后,我添加了一些逻辑,以将收集的访问令牌传递给AJAX url的参数字符串。 (在两个位置查找“ $ get”,一个位置设置值,另一个位置将其附加到AJAX网址。)

在get-posts.php中,我删除了向Facebook API请求访问令牌的代码。相反,我只是基于Facebook PHP SDK中的setDefaultAccesstoken()函数,根据通过fb-config.php通过GET从fb-config.php中传递的内容设置访问令牌,该参数名为“ accessToken”。

如其他地方所述,您可以继续通过GET,REQUEST或$ _SESSION将访问令牌的值逐页传递,只要您保持会话并在随后的每个后续时刻通过setDefaultAccessToken()函数通知Facebook页面。

答案 1 :(得分:2)

答案在注释中,但实际上有更好的方法。


首先,要直接回答您的问题,问题是传递给fb-callback.php的“代码”尚未传递给调用$helper->getAccessToken()

的脚本。

该功能的文档(位于https://developers.facebook.com/docs/php/FacebookRedirectLoginHelper/5.0.0处)

  

尝试从授权码获取访问令牌。这个   方法将向Graph API发出请求并返回响应。如果   在该过程中出现错误,FacebookSDKException将被   抛出。如果CSRF也将引发FacebookSDKException   验证失败。

     

如果在代码参数中找不到授权码   URL,此方法将返回null。

还有两点需要注意:

  • “状态”(跨站点伪造令牌)是会话的一部分;你不 只要您在同一个域中,就需要显式传递它, 但是您可能同时需要session_start()login中的get-posts getAccessToken脚本<?php require_once("config.php"); $code = $_GET['code']; // warning: add validation code exists, sanitise etc. ?> <html> <head> <script type='text/javascript' src='jquery.js'></script> <script> var $j = jQuery.noConflict(); $j(document).ready(function () { $j.ajax({ type: "GET", url: "get-posts.php?code=<?php echo $code; ?>", cache: false, success: function (html) { setTimeout(function () { $j('#updateDiv').html(html); }, 1000); } }); }); </script> </head> <body> <div id='updateDiv'><img src='spinning.gif' alt='processing...'></div> </body> </html> 有一个参数 函数,它应该是原始URL

非常简单

  1. 将session_start()添加到登录脚本和get-posts.php
  2. 将fb-callback.php修改为类似

get-posts

(注意:我讨厌嵌入式PHP-这仅是示例)


但是:您应该做的是在函数之间传递访问令牌,而不是在oAuth代码之间传递。上面的方式(通过oAuth代码)是一次性的;但是,您可以第二次/第三次/第四次致电get-posts.php,如果您首先拥有访问令牌,它将可以使用。

1)在顶部的fb-callback.php中进行令牌交换(速度很快,不需要微调器),获取令牌(FB库存储在会话变量/ cookie中,或者您可以自己进行)然后显示带有微调框和AJAX调用的HTML页面。

2)在顶部的fb-callback.php中进行令牌交换(速度很快,不需要微调器),获取令牌(FB库存储在会话变量/ cookie中,或者您可以自己完成)然后快速重定向到另一个显示微调器并进行AJAX调用的页面。

在这两个方面要注意的关键思想是您正在传递访问令牌;在lhs & rhs // Are parameter. 中,选中“我是否具有访问令牌;如果没有,请显示登录按钮;如果有,请致电Facebook”。