【问题标题】:Cannot obtain page access token through an app that is granted the manage_pages permission无法通过被授予 manage_pages 权限的应用获取页面访问令牌
【发布时间】:2013-04-19 20:24:39
【问题描述】:

我正在尝试开发一个 PHP 应用程序,当我处于离线状态且根本没有登录 Facebook 时,它可以让我通过 cronjob 在我的页面上自动发布新帖子。我知道 offline_access 权限早已不复存在,但Removal of offline_access permission 文章明确指出以下内容:

场景 5:页面访问令牌

当用户授予应用 ma​​nage_pages 权限时,应用能够 获取用户管理的页面的页面访问令牌 查询 [User ID]/accounts Graph API 端点。随着迁移 启用,当使用短期用户访问令牌查询此 端点,获得的页面访问令牌也是短暂的。

将短期用户访问令牌交换为长期访问 使用前面解释的端点和步骤的令牌。通过使用 长期用户访问令牌,查询 [User ID]/accounts 端点 现在将为以下页面提供不会过期的页面访问令牌 用户管理。这也适用于使用非过期查询 通过已弃用的 offline_access 获得的用户访问令牌 权限。

... 这让我觉得像我想的那样的自动化 PHP 解决方案确实可以设计。所以我继续创建了一个新的应用程序并授予 ma​​nage_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);

...相反,我得到:

致命错误: Uncaught OAuthException: (#200) 用户没有 授权应用程序执行此操作

解决方案

先生的帮助下。 Mohammed Alghbari,我能够在这个问题上取得合理的进展并最终找到解决方案。

按照他的建议,我需要先生成一个用户访问令牌,发出这样的请求:

https://graph.facebook.com/me/accounts?access_token=USER_ACCESS_TOKEN

为了检索实际的页面访问令牌并发布到页面。所以我意识到当我通过 PHP SDK 生成的登录链接登录时,一个 USER_ACCESS_TOKEN 为我存储在一个 $_SESSION 变量中。我拿到了那个令牌,向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-&gt;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'));

【问题讨论】:

    标签: php facebook-graph-api facebook-php-sdk facebook-apps facebook-access-token


    【解决方案1】:

    maringtr,

    要与页面交互,您需要使用页面访问令牌(检查访问令牌类型:Access Token Types

    类型有:用户访问令牌、页面访问令牌、应用访问令牌

    可以用这样的图生成:

    https://graph.facebook.com/me/accounts?access_token=USER_ACCESS_TOKEN
    

    上图将为您提供您管理的页面列表以及详细信息(页面名称、ID、访问令牌)

    您可以测试页面访问令牌以使用图表获取您的页面供稿(将 Page_ID 替换为您的页面 id,将 PAGE_ACCESS_TOKEN 替换为从上述图表生成的页面访问令牌)

    https://graph.facebook.com/PAGE_ID/feed?access_token=PAGE_ACCESS_TOKEN&message=Testing
    

    欲了解更多信息和示例:Log In as Page

    问候,

    【讨论】:

    • 感谢您的回复。问题是我无法以编程方式获取页面访问令牌,因为在尝试请求 $pages = $facebook-&gt;api("/$accountID/accounts/"); 以获取页面令牌时,我得到了 Fatal error: Uncaught OAuthException: A user access token is required to request this resource.。我发现我可以在登录时获取 $_SESSION 变量中记录的用户令牌,然后注销,但继续使用它来执行$facebook-&gt;api("/$accountID/accounts/"); 并获取页面令牌。我能够使用获得的令牌发布到我的页面。谢谢!
    • 嗯,实际上它似乎在注销后停止工作。我刚刚使用session_destroy() 销毁了我的会话,现在我得到了同样的错误。
    • Welcome My Friend,您可以在访问令牌失效后使用refresh Token刷新您的访问令牌,,,您在生成页面访问令牌之前是否生成了用户访问令牌?
    • 谢谢你 Mohammed,我已经在我原来的帖子中发布了对你的完整回复(作为评论回复发布太长了)
    【解决方案2】:

    请授予 status_update,正如我在此处解释的 why does posting to facebook page yield "user hasn't authorized the application"

    【讨论】:

    • 我授予了 status_update 权限,但Uncaught OAuthException: (#200) The user hasn't authorized the application to perform this action 错误仍然存​​在。
    猜你喜欢
    • 2012-08-16
    • 2018-06-13
    • 2019-03-21
    • 2022-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    相关资源
    最近更新 更多