Facebook SDK 访问令牌和 ajax
Facebook SDK access tokens and ajax
我按照 PHP 文档的 Facebook SDK 创建了两个文件,login.php 和 fb-callback.php,所有查找逻辑都在 fb-callback.php 中。当我这样做时,一切正常。
但我想将查找逻辑移动到 get-posts.php 并通过 ajax 从 fb-callback.php 调用它。当我这样做时,我似乎无法获得访问令牌。我收到下面指出的错误,"Access Token: Bad request".
我已将 fb-config.php 和 get-posts.php 注册为有效的 OAuth 重定向 URI。那么如何获得正确的参数来获取-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;
}
...
答案在评论里,其实还有更好的方法。
首先,直接回答你的问题,问题是传递给 fb-callback.php 的 "code" 没有传递给调用 $helper->getAccessToken()
[=20 的脚本=]
该函数的文档(在 https://developers.facebook.com/docs/php/FacebookRedirectLoginHelper/5.0.0)指出
Attempts to obtain an access token from an authorization code. This
method will make a request to the Graph API and return a response. If
there was an error in that process a FacebookSDKException will be
thrown. A FacebookSDKException will also be thrown if the CSRF
validation fails.
If no authorization code could be found from the code param in the
URL, this method will return null.
还有两点需要注意:
- "state"(跨站点伪造令牌)是会话的一部分;你不
只要您在同一个域中,就需要显式传递它,
然而你可能需要
session_start()
在 login
和
get-posts
scripts 有一个参数给 getAccessToken
函数应该是 ORIGINAL 的 URL
非常简单
- 将 session_start() 添加到登录脚本和 get-posts.php
- 将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
一次 second/third/fourth ,如果您先拥有访问令牌,它就会工作。
1) 在顶部的 fb-callback.php 中进行令牌交换(速度很快,不需要旋转器),获取令牌(FB 库存储在会话 variable/cookie 中,或者你可以自己做)然后用微调器和 AJAX 调用显示 HTML 页面。
2) 在顶部的 fb-callback.php 中进行令牌交换(速度很快,不需要旋转器),获取令牌(FB 库存储在会话 variable/cookie 中,或者你可以自己做)然后快速重定向到另一个显示微调器的页面并进行 AJAX 调用。
在这两个方面要注意的关键思想是您正在传递访问令牌;在 get-posts.php
中检查 "do I have access token; if not - show login button; if so - call facebook"。
下面是实际代码,其中解释了必须更改的内容:
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 url 的地方。)
在 get-posts.php 中,我删除了向 Facebook API 请求访问令牌的代码。相反,我只是根据来自 fb-config.php 通过 GET 在名为 "accessToken" 的参数中使用来自 Facebook PHP SDK 的 setDefaultAccesstoken() 函数传递的内容设置访问令牌。
如其他地方所述,您可以继续通过 GET、REQUEST 或 $_SESSION 将访问令牌的值传递到一页又一页,只要您保持会话并通过 setDefaultAccessToken() 函数通知 Facebook每个后续页面。
我按照 PHP 文档的 Facebook SDK 创建了两个文件,login.php 和 fb-callback.php,所有查找逻辑都在 fb-callback.php 中。当我这样做时,一切正常。
但我想将查找逻辑移动到 get-posts.php 并通过 ajax 从 fb-callback.php 调用它。当我这样做时,我似乎无法获得访问令牌。我收到下面指出的错误,"Access Token: Bad request".
我已将 fb-config.php 和 get-posts.php 注册为有效的 OAuth 重定向 URI。那么如何获得正确的参数来获取-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;
}
...
答案在评论里,其实还有更好的方法。
首先,直接回答你的问题,问题是传递给 fb-callback.php 的 "code" 没有传递给调用 $helper->getAccessToken()
[=20 的脚本=]
该函数的文档(在 https://developers.facebook.com/docs/php/FacebookRedirectLoginHelper/5.0.0)指出
Attempts to obtain an access token from an authorization code. This method will make a request to the Graph API and return a response. If there was an error in that process a FacebookSDKException will be thrown. A FacebookSDKException will also be thrown if the CSRF validation fails.
If no authorization code could be found from the code param in the URL, this method will return null.
还有两点需要注意:
- "state"(跨站点伪造令牌)是会话的一部分;你不
只要您在同一个域中,就需要显式传递它,
然而你可能需要
session_start()
在login
和get-posts
scripts 有一个参数给getAccessToken
函数应该是 ORIGINAL 的 URL
非常简单
- 将 session_start() 添加到登录脚本和 get-posts.php
- 将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
一次 second/third/fourth ,如果您先拥有访问令牌,它就会工作。
1) 在顶部的 fb-callback.php 中进行令牌交换(速度很快,不需要旋转器),获取令牌(FB 库存储在会话 variable/cookie 中,或者你可以自己做)然后用微调器和 AJAX 调用显示 HTML 页面。
2) 在顶部的 fb-callback.php 中进行令牌交换(速度很快,不需要旋转器),获取令牌(FB 库存储在会话 variable/cookie 中,或者你可以自己做)然后快速重定向到另一个显示微调器的页面并进行 AJAX 调用。
在这两个方面要注意的关键思想是您正在传递访问令牌;在 get-posts.php
中检查 "do I have access token; if not - show login button; if so - call facebook"。
下面是实际代码,其中解释了必须更改的内容:
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 url 的地方。)
在 get-posts.php 中,我删除了向 Facebook API 请求访问令牌的代码。相反,我只是根据来自 fb-config.php 通过 GET 在名为 "accessToken" 的参数中使用来自 Facebook PHP SDK 的 setDefaultAccesstoken() 函数传递的内容设置访问令牌。
如其他地方所述,您可以继续通过 GET、REQUEST 或 $_SESSION 将访问令牌的值传递到一页又一页,只要您保持会话并通过 setDefaultAccessToken() 函数通知 Facebook每个后续页面。