Facebook图谱API - OAuth令牌

26

我正在尝试使用新的图形 API 检索数据,但是我从 OAuth 获取的令牌似乎无效。

我正在进行以下调用:

$token = file_get_contents('https://graph.facebook.com/oauth/access_token?type=client_cred&client_id=<app_id>&client_secret=<app secret>');

这将返回一个字符串长度为41个字符的令牌。为了给你一个返回值示例,我提供了下面一个样本(将所有数字转换为0,所有大写字母转换为“ A”,所有小写字母转换为“ a”)。

access_token=000000000000|AaaAaaAaaAAaAaaaaAaaAa0aaAA.

我拿起这个访问令牌并将其附加到数据的调用请求中,但它似乎不是正确的令牌,因为它什么也没有返回。我按照以下方式进行数据调用:

file_get_contents('https://graph.facebook.com/<my_page's_id>/statuses?access_token=000000000000|AaaAaaAaaAAaAaaaaAaaAa0aaAA.')

当我直接通过浏览器手动检索此页面时,我会收到一个500/Internal Server错误消息。

任何帮助将不胜感激。


更新:

我已经从file_get_contents()更改为curl方法。 通过检索标头,我得到以下错误消息...

{"error":{"type":"OAuthException","message":"Missing client_id"}}

但是我的post数组中包含'client_id'?!


嗨,你还有同样的问题吗? - Danish Iqbal
11个回答

24
不要使用type=client_cred,这不是用户授予您的应用程序使用的访问令牌。您不需要redirect_uri或code或任何批准即可获取client_cred类型的访问令牌。
Facebook在此时实现了OAuth 2的早期草案。因此,还没有支持“state”。
但是,您可以将状态后缀添加到redirect_uri中,重要的是要注意您指定的站点网址(即redirect_uri)不应在客户端状态中有任何问号,编码或未编码。如果您这样做,您将收到可怕的“验证验证代码错误”。
不要像这样使用: http://www.Redirect.com? 正确的URL是: http://www.Redirect.com/ 希望对您有所帮助。

3
这是正确的答案。你的redirect_uri必须以/结尾。谢谢告诉我们! - Sebastian Hoitz
绝对准确100%。另外,作为注释:在传递给PHP SDK的getLoginUrl()方法的$params数组中,不要使用redirect_uri!!!否则会破坏它。 - Tom Roggero
竟然还少了斜线。糟糕! - Spedge

16

这对我有效 :-)

header('Location: https://graph.facebook.com/oauth/access_token?' . http_build_query(array(
    'client_id'     => FB_APP_ID,
    'type'          => 'client_cred',
    'client_secret' => FB_SECRET,
    'code'          => $code)));

当然,你可以使用file_get_contents函数获取内容,并从响应中解析出令牌。


1
+1 类型为 client_cred 的方式对我有效。但是该页面没有重定向到我的 redirect_uri。 - Richard
type=client_cred 似乎会为您发出一个没有用户会话的令牌(如“作为应用程序进行身份验证”中所述)。它基本上的行为就像您根本没有传递代码一样。没有用户会话的令牌基本上可以正常工作,但是某些需要知道当前用户是谁的API无法正常工作,尤其是:http://graph.facebook.com/me。我完全无法按照这里或Facebook的说明获取带有用户会话的令牌。有点令人沮丧。 - Brian Duff
3
原文:Turns out that facebook's oauth implementation has some quirky bugs related to the content of the redirect_uri parameter. If your redirect uri contains certain chars (e.g. a correctly url encoded colon), it will choke.翻译:原来Facebook的OAuth实现存在一些与redirect_uri参数内容相关的奇怪错误。如果你的重定向URI包含某些字符(例如正确的URL编码冒号),它将会出错。 - Brian Duff
确认Brian的评论 - 如果我的redirect_uri上有任何querystring参数,当我去获取令牌时Facebook会出现问题; 没有参数就可以正常工作。在设置redirect_uri参数之前,我正确地进行了url编码。Facebook可能会对整个内容进行多次url解码,因此redirect_uri上的参数似乎是主查询字符串的一部分。 - David Pope

8
我遇到了完全相同的问题,但结果并不是redirect_uri参数的编码问题,也不是我有一个尾随斜杠或问号,而只是我传递了两个不同的重定向URL(当时没有阅读规范)。
redirect_uri仅在第一次(第一次)用作重定向,以使用“code”令牌将其重定向回依赖方。第二次,redirect_uri被传递回auth服务器,但这次它不像您期望的那样用于重定向,而是由身份验证服务器用于验证代码。服务器响应access_token。

https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-05#section-3.5.2

你会注意到 Facebook 的文档(非常糟糕)中提到要 "通过 fetching https://graph.facebook.com/oauth/access_token 来将其转换为访问令牌。"
总之,我不需要对 Uri 进行编码或进行任何特殊处理,只需两次传递相同的 redirect_uri,并 fetch 第二个页面以获取其中的 access_token 即可。

6

您可以通过终端(适用于OSX用户)使用curl请求访问令牌:

curl -F type=client_cred -F client_id=xxxxxxxxxxxxxxx -F client_secret=c0f88xxxxxxxxxxxxxxxxxx1b949d1b8 https://graph.facebook.com/oauth/access_token

一旦您获得了访问令牌,您可以在未来的curl请求中使用它通过新的图形API进行更改:

向个人资料ID发布消息:

curl -F 'access_token=xxxxxxxxxxxxx|mGVx50lxxxxxxxxxxxxhzC2w.'  -F 'message=Hello Likers'  -F 'id=1250000000000905'  https ://graph.facebook.com/feed

访问令牌不会在几天内过期吗? - Jayapal Chandran
嗨,Volcanic,我正在尝试使用这种技术来发布喜欢的网页的动态,这应该可以实现吗?你有什么想法吗?http://stackoverflow.com/questions/10419371/how-to-programmatically-publish-to-a-facebook-feed-for-a-liked-webpage - waterlooalex

3
请注意,'type' => 'client_cred' 仅是绕过下面问题的一种方式,尽管如此,上述方法同样适用。用户授权您的应用程序后,我们将带有验证字符串的参数代码重定向回您指定的重定向URI,该代码可以交换为oauth访问令牌。通过获取 https://graph.facebook.com/oauth/access_token 来将其交换为访问令牌。传递与上一步中完全相同的 redirect_uri:通过:由:http://developers.facebook.com/docs/api另请参阅:http://forum.developers.facebook.net/viewtopic.php?pid=238371

1
谢谢!完全相同的 redirect_uri 帮了我。 :) - Yoh Suzuki

2
尝试遵循API,即不使用"type"但添加"redirect_uri"和"code"(即使我们不需要它):
$token = file_get_contents('https://graph.facebook.com/oauth/access_token?client_id=<app_id>&client_secret=<app secret>&redirect_uri=<url>&code=<code>');

2
也许你的问题已经解决了,但我还没有看到你接受的答案,也许这个答案会帮助那些遇到相似问题的人。
首先,我们需要创建我们的应用程序实例。
$facebook = new Facebook(array(
  'appId' => '149865361795547',
  'secret' => 'ee827a8df6202e1857b3fc28f3185a61',
  'cookie' => true,
)); 

获取 access_token 的简易方法

$token = $facebook->getAccessToken();

根据你的问题,获取页面状态。

$response = $facebook->api($pageID . '/feed','get',$token);

thanks..


0

请确保您已对查询参数进行了URL编码,您的应该是:

000000000000%7CAaaAaaAaaAAaAaaaaAaaAa0aaAA

注意:似乎还需要 type 参数,如果没有它,您也将收到带有消息的 500 错误。
{
   "error": {
   "type": "OAuthException",
   "message": "Error validating verification code."
   }
}

与其他缺少参数时得到的消息不同,它会返回一个错误。在文档中没有看到提到这一点。


在什么时候需要类型参数?它包含在 $token = file_get_contents(...) 中。 - Simon R
哦,抱歉,那是给自己的一个提示——你已经在访问令牌部分拥有了它。 - user242766
1
嗨,我得到了以下错误:{ "error":{ "type":"OAuthException", "message":"缺少redirect_uri参数。" } } 重定向URL可能存在什么问题?我希望我提供的一切都是正确的。 - shasi kanth

0
您还可能因为您的连接 URL 不是重定向 URI 的基础而出现此错误。例如:
Connect URL: http://www.example.com/fb/connect/

Redirect URI: http://www.example.com/fb/connect/redirect

我遇到了一个问题,我的重定向URI与连接URL相同,但我忘记在重定向URI上添加尾随的/,因此FB将它们视为不同并未能通过身份验证。

0

抱歉在旧问题中发布。由于最近的fb访问更改,我有这个代码正在工作,并认为我会为任何需要帮助的人发布。这种方法与jQuery ajax非常配合,消除了Facebook给出的redirect_uri示例。

$ch = curl_init("https://graph.facebook.com/oauth/access_token?client_id=INSERT_YOUR_APP_ID_HERE&client_secret=INSERT_YOUR_APP_SECRET_HERE&grant_type=client_credentials");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 30000);
$data = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
curl_close($ch);

if ($curl_errno > 0) 
{
        echo "cURL Error ($curl_errno): $curl_error\n";
} 
else 
{
    echo $data;
}

输出一个公共可用的access_token,以便向非Facebook用户展示。例如,通过网站上的Graph API显示Facebook页面Feed墙。 access_token=191648007534048|eVilnMh585rlQLZLvBAmqM6s-1g


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接