我正在尝试开发一个PHP应用程序,它可以让我在离线且根本没有登录Facebook时,通过cronjob自动在页面上发布新帖子。我知道offline_access权限早已消失,但"删除offline_address权限"一文明确指出:
场景5:页面访问令牌
当用户授予应用程序manage_pages权限时,该应用程序能够获取用户通过管理的页面的页面访问令牌查询[用户ID]/accounts Graph API端点。随着迁移启用,当使用短期用户访问令牌查询此端点,获得的页面访问令牌也是短暂的。
将短期用户访问令牌交换为长期访问使用端点和前面解释的步骤进行标记。通过使用长期用户访问令牌,查询[user ID]/accounts端点现在将为以下页面提供不会过期的页面访问令牌用户进行管理。这也适用于使用非过期查询通过不推荐使用的offline_access获得的用户访问令牌准许
这让我认为,像我所想的那样,一个自动化的PHP解决方案确实是可行的。因此,我继续创建了一个新的应用程序,并授予了manage_pages权限以及publish_actions许可。
然而,我的代码:
<?php
require_once("sdk/facebook.php");
$config = array();
$config['appId'] = MY_APP_ID;
$config['secret'] = MY_APP_SECRET;
$config['fileUpload'] = false; // optional
$facebook = new Facebook($config);
$accountID = MY_ACCOUNT_ID;
$pages = $facebook->api("/$accountID/accounts/");
var_dump($pages);
?>
返回以下错误:
致命错误:未捕获OAuthException:需要用户访问令牌请求此资源。
我做错了什么?
更令人困惑的是,与此同时,这里的这段代码在我的Wall上发布了一个状态更新,没有任何问题(我仍然没有登录Facebook或任何东西(
<?php
require_once("sdk/facebook.php");
$config = array();
$config['appId'] = MY_APP_ID;
$config['secret'] = MY_APP_SECRET;
$config['fileUpload'] = false; // optional
$token_url = "https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $config['appId'] .
"&client_secret=" . $config['secret'] .
"&grant_type=client_credentials";
$app_token = str_replace('access_token=','',file_get_contents($token_url));
$facebook = new Facebook($config);
$args = array(
'access_token' => $app_token,
'message' => 'test post via app access token'
);
$accountID = MY_ACCOUNT_ID;
$post_id = $facebook->api("/$accountID/feed", "post", $args);
?>
如果我做
$post_id = $facebook->api("/$myPageID/feed", "post", $args);
相反,我得到了:
致命错误:未捕获OAuthException:(#200(用户尚未授权应用程序执行此操作
解决方案
在先生的善意帮助下。Mohammed Alaghbari,我在这个问题上取得了合理的进展,最终找到了解决方案。
正如他所建议的,我需要首先生成一个用户访问令牌,发出这样的请求:
https://graph.facebook.com/me/accounts?access_token=USER_ACCESS_TOKEN
为了检索实际的页面访问令牌并发布到页面。因此,我意识到,当我通过PHP SDK生成的登录链接登录时,在$_SESSION变量中为我存储了一个USER_ACCESS_TOKEN。我获取了该令牌,向https://graph.facebook.com/me/accounts?access_token=USER_ACCESS_TOKEN
发出请求,检索PAGE_ACCESS_token并使用它成功地将测试消息发布到我的页面。
然而,我随后注销并发出了session_destroy();
。令我惊讶的是,在我这样做的那一刻,我的代码又开始抛出A user access token is required to request this resource.
异常。我很沮丧。
然后,我决定手动请求https://graph.facebook.com/MY_ACCOUNT_ID/accounts/?MY_USER_ACCESS_TOKEN
,看看会发生什么。令我更惊讶的是,GRAPH API接受了USER_ACCESS_TOKEN并返回了所有有效的页面令牌。我很沮丧为什么我在SDK中得到一个异常,但当我直接向GRAPH API发出请求时没有错误,所以我决定开始调试base_facebook.php。我使用的php SDK是版本3.2.2。
经过数小时的搜索,结果发现位于base_facebook.php第899行的这段代码无故抛出异常(有点像(
if (!isset($params['access_token'])) {
$params['access_token'] = $this->getAccessToken();
}
当我对$params['access_token'] = $this->getAccessToken();
行进行注释时,我的PHP SDK请求再次开始返回有效的令牌。
奇怪。我想知道这是PHP SDK中的错误,还是我的代码有问题。我的最终代码大致如下:
<?php
require_once("sdk/facebook.php");
$config = array();
$config['appId'] = MY_APP_ID;
$config['secret'] = MY_APP_SECRET;
$config['fileUpload'] = false; // optional
$facebook = new Facebook($config);
$token = MY_USER_TOKEN; // extracted from $_SESSION
$response = $facebook->api("/MY_ACCOUNT_ID/accounts/?access_token=$token");
// code that extracts the page token from $response goes here
$args = array(
'access_token' => MY_PAGE_TOKEN,
'message' => 'test post via app access token'
);
$post_id = $facebook->api("/MY_PAGE_ID/feed", "post", $args); // It works!!
?>
编辑#2
经过进一步的测试,结果表明,你可以修改,而不是注释899行
$facebook->api("/MY_ACCOUNT_ID/accounts/?access_token=MY_ACCESS_TOKEN');
至
$facebook->api("/MY_ACCOUNT_ID/accounts/", 'get', array('access_token' => 'MY_ACCESS_TOKEN'));
maringgtr,
要与页面交互,您需要使用页面访问令牌(检查访问令牌类型:访问令牌类型(
类型有:用户访问令牌、页面访问令牌、应用程序访问令牌
可以用这样的图形生成:
https://graph.facebook.com/me/accounts?access_token=USER_ACCESS_TOKEN
上图将为您提供一个您管理的页面列表,其中包含详细信息(页面名称、ID、访问令牌(
您可以测试页面访问令牌以使用Graph获取页面馈送(用您的页面id替换Page_ID
,用从上述Graph生成的页面访问令牌替换PAGE_ACCESS_TOKEN
(
https://graph.facebook.com/PAGE_ID/feed?access_token=PAGE_ACCESS_TOKEN&message=Testing
有关更多信息和示例:以页面身份登录
此致,
请授予status_update,正如我在这里解释的,为什么在facebook页面上发帖会产生"用户已经';t授权该申请";