Facebook SDK токены доступа и AJAX

Я следовал за SDK Facebook для документов PHP и создал два файла, login.php и fb-callback.php со всей логикой поиска в fb-callback.php. Когда я делаю это, все работает нормально.

Но я хочу переместить логику поиска в get-posts.php и вызвать ее через ajax из fb-callback.php. Когда я делаю это, я не могу получить токен доступа. Я получаю ошибку, указанную ниже: «Токен доступа: неверный запрос».

Я зарегистрировал как fb-config.php, так и get-posts.php как допустимые URI перенаправления OAuth. Итак, как мне получить правильные параметры для 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();
?>

фб-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>

получить-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;
}

...

10

Решение

Вот фактический код, который работает с пояснениями к тому, что пришлось изменить ниже:

фб-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>

получить-posts.php

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

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

...

Так что изменилось? Во-первых, мне нужно было получить код доступа в fb-callback.php, а не в get-posts.php. Поэтому я переместил логику для получения кода доступа и проверки на наличие ошибок обратно в fb-callback.php. Затем я добавил логику для передачи собранного токена в строку параметров URL-адреса AJAX. (Ищите «$ get» в двух местах: один раз, когда я устанавливаю значение, и один раз, когда я присоединяю его к URL-адресу AJAX.)

В get-posts.php я удалил код, который запрашивает у API Facebook токен доступа. Вместо этого я просто установил токен доступа на основе того, что было передано из fb-config.php через GET в параметре с именем «accessToken» с помощью функции setDefaultAccesstoken () из Facebook PHP SDK.

Как уже было отмечено, вы можете продолжать передавать значение токена доступа через GET, REQUEST или $ _SESSION на страницу за страницей, если вы поддерживаете сеанс и информируете Facebook через функцию setDefaultAccessToken () на каждой последующей странице.

3

Другие решения

Ответ в комментариях, но на самом деле есть лучшие способы.


Во-первых, чтобы ответить на ваш вопрос напрямую, проблема в том, что «код», переданный в fb-callback.php, не был передан в скрипт, который вызывает $helper->getAccessToken()

Документы для этой функции (в https://developers.facebook.com/docs/php/FacebookRedirectLoginHelper/5.0.0) состояния

Попытки получить токен доступа из кода авторизации. это
Метод сделает запрос к Graph API и вернет ответ. Если
в этом процессе произошла ошибка, исключение FacebookSDKException будет
выброшены. Исключение FacebookSDKE также будет выброшено, если CSRF
проверка не пройдена.

Если код авторизации не найден из параметра кода в
URL, этот метод вернет ноль.

Следует отметить еще два момента:

  • «Состояние» (маркер подделки сайта) является частью сеанса; вы не
    необходимо явно передать его, если вы находитесь в одном домене,
    однако вам может понадобиться session_start() в обоих login а также
    get-posts сценарии Есть параметр для getAccessToken
    функция, которая должна быть URL ОРИГИНАЛА

Так очень просто

  1. Добавьте session_start () к сценарию входа и get-posts.php
  2. Измените fb-callback.php так, чтобы он был похож на

.

<?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>

(Примечание: я ненавижу встроенный PHP — это только пример)


Однако, что вы должны делать, это передавать токен доступа между функциями, а не код oAuth. То, как вы это сделали выше (передача кода oAuth), является одноразовым; Однако вы можете позвонить get-posts во второй / третий / четвертый раз, и это сработает, если у вас будет первый токен доступа.

1) Выполните обмен токенами в fb-callback.php вверху (это быстро, нет необходимости в счетчике), возьмите токен (который библиотека FB хранит в переменной / cookie сеанса, или вы можете сделать это самостоятельно), а затем покажите HTML-страница со спиннером и вызовом AJAX.

2) Выполните обмен токенами в fb-callback.php вверху (это быстро, нет необходимости в спиннер), возьмите токен (который библиотека FB хранит в переменной / cookie сеанса, или вы можете сделать это самостоятельно), а затем быстро перенаправить на другую страницу, которая показывает счетчик и выполняет вызов AJAX.

В обоих случаях важно отметить, что вы передаете токен доступа; в get-posts.php установите флажок «есть ли у меня токен доступа; если нет — показать кнопку входа в систему; если это так — позвоните в Facebook».

2

По вопросам рекламы [email protected]