在C#SDK中请求页面访问令牌

时间:2012-11-16 17:47:30

标签: facebook-graph-api oauth facebook-c#-sdk

作为简单后台应用程序的概念验证,我使用Graph API Explorer为我的应用程序创建一个访问令牌,以便将内容发布到我维护的页面的墙上。它工作正常。然而,自然地,令牌到期。

所以现在我正在尝试让后台应用程序在每次运行时自动请求新的页面访问令牌。我在找到如何做到这一点的具体定义方面遇到了很多麻烦。关于Facebook和访问令牌的信息并不缺乏,但似乎没有任何东西可以证明如何将后台应用程序发布到页面上。 (不发布到用户的墙上,不向用户显示登录对话框,因为它是后台应用程序等)。

我可以通过阅读来自此网址的网络请求的响应,轻松地在代码中获取访问令牌:

https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id={MY_APP_ID}&client_secret={MY_APP_SECRET}

当然,尝试发布到页面墙时,“访问令牌”不起作用。它表示用户尚未授权应用程序执行此操作。我正在执行的操作非常简单:

var client = new FacebookClient(GetFacebookAccessToken());
dynamic parameters = new ExpandoObject();
parameters.message = "this is a test";
dynamic result = client.Post("{MY_PAGE_ID}/feed", parameters);

我在某些地方读过,我需要使用第一个访问令牌发出第二个请求来获取页面访问令牌。但我似乎无法找到如何做到这一点的例子。

有人可以为我阐明这个吗?

  • 我有一个Facebook页面。
  • 我有一个Facebook应用程序,除了提供本地后台应用程序访问所述页面的方法之外别无其他用途。
  • 我只需要该应用程序就可以进行身份​​验证,以便它可以向页面发布内容。
  • (如果我需要在Facebook界面中执行一个步骤以永久授予应用程序执行此操作的权限,我认为我已经执行了该步骤但是以某种方式进行双重检查会很好。)

编辑:我已经向我描述过我需要获取一个长期存在的用户访问令牌,并使用它来获取页面访问令牌。理论是所述页面访问令牌不会过期。然而,我不清楚的是如何实现这一点。

我已阅读the page describing the deprecation of offline_access以及the page describing server-side access。但是,我显然是在误解某些东西。在前者中,它引用后者来获得适当的令牌。但是,后者包括向用户显示登录,让他们接受权限以及使用该登录的响应的步骤。

作为一个无人值守的后台进程,向用户(可能是我)提出任何问题并不是一个真正的选择。我也被告知我不能从我的浏览器一次性请求获取访问令牌,因为根据定义,这是客户端交互而不是必要的服务器端流程的一部分。 (对我来说,如果一个RESTful请求来自一个Web浏览器而不是来自一个应用程序,那么该服务似乎很奇怪,但我对OAuth或Facebook API不太熟悉,无法真正进行该调用。)

因此,如果我可以执行一些手动步骤来获取应用程序发布到Facebook页面的永久访问令牌,那么这些步骤是什么?相反,如果我可以在应用程序中执行一些自动化步骤以在每次运行时获取访问权限,那么这些步骤是什么?

(从应用程序中再进行一些API调用会将一两个运行时间添加到另外一天的过程中,因此对我采取哪种方法没有任何区别。)

2 个答案:

答案 0 :(得分:9)

首先,我刚进入Facebook应用程序设置并重新启用了已弃用的“离线访问”权限。所述应用程序设置可以在以下URL中找到:

https://developers.facebook.com/apps/{APPLICATION_ID}/advanced

但是,由于所有内容都将该设置称为“已弃用”,因此我不想将其用作长期解决方案。它可能被完全删除,在某些情况下可能不安全等。更好地使用推荐的功能。

所以这就是我能够通过更新的文档,过时的文档,过时的互联网帖子和PHP代码拼凑而成的东西,这些代码主要是假设功能在所有情况下都不是真的......

访问Graph API Explorer,然后从下拉菜单中选择您的Facebook应用程序。单击“获取访问令牌”并选择所需的权限。 (对于我的,我进入了“扩展权限”选项卡并选择了“托管页面”和“发布流”。)您将被提示(在我的浏览器中它位于新选项卡中),其中有一个熟悉的Facebook应用程序要求的屏幕您(即用户)授予您刚刚选择的权限。 (如果您以前曾同意使用Facebook应用程序,那么您之前就已经看过了。)

它在Graph API Explorer中生成的值(一长串随机字符)是您的“短暂用户访问令牌”。

正如“方案4:客户端OAuth和通过新端点扩展Access_Token到期时间”中所述here在Web浏览器中访问此URL:

https://graph.facebook.com/oauth/access_token?
  client_id={APPLICATION_ID}
  &client_secret={APPLICATION_SECRET}
  &grant_type=fb_exchange_token
  &fb_exchange_token={SHORT_LIVED_USER_ACCESS_TOKEN}

(您可以在Facebook应用的基本设置页面上获取{APPLICATION_SECRET}值:https://developers.facebook.com/apps/{APPLICATION_ID}/summary

这将返回另一个访问令牌:

access_token={LONG_LIVED_USER_ACCESS_TOKEN}&expires=5184000

access_token值(另一长串随机字符)是您的“Long Lived User Access Token”。 expires值以秒为单位,转换为60天。

现在我们跳到Page API reference并查看Page Access Tokens上的部分。这一点,以及示例here的图谱API请求的基本结构(向下滚动到显示包含access_token说明符的样例链接的项目符号列表的部分,您需要在此处指定,因为您要求提供非公开信息,请您在浏览器中提出要求:

https://graph.facebook.com/{FACEBOOK_USER_ID}/accounts?
  access_token={LONG_LIVED_USER_ACCESS_TOKEN}

这将返回一个JavaScript对象,其中包含有关您的用户帐户控制的Facebook页面和Facebook应用程序的大量有用信息。在我的情况下,页面和应用程序具有相同的名称,但很容易将它们与category值区分开,或者如果所有其他方法都失败,则表示id值。找到计算机上运行的后台应用程序需要访问的页面,并复制其access_token(第三个也是最后一个长串随机字符)。整个节点看起来像这样:

{
  "name": "Some Facebook Application Name",
  "access_token": "{LONG_LIVED_PAGE_ACCESS_TOKEN}",
  "category": "Musician/band",
  "id": "{APPLICATION_ID}",
  "perms": [
    "ADMINISTER",
    "EDIT_PROFILE",
    "CREATE_CONTENT",
    "MODERATE_CONTENT",
    "CREATE_ADS",
    "BASIC_ADMIN"
  ]
}

这是您的“Long Lived页面访问令牌”。这是用于在代码中初始化FacebookClient对象的值。然后,发布简单的状态更新就像:

var client = new FacebookClient("{LONG_LIVED_PAGE_ACCESS_TOKEN}");
dynamic parameters = new ExpandoObject();
parameters.message = "This is a my status update.";
dynamic result = client.Post("{FACEBOOK_PAGE_ID}/feed", parameters);

据说这个“Long Lived页面访问令牌”在60天后过期,就像“Long Lived User Access Token”那样。我想,我会在59天内发现。


注意:我的示例中的花括号是实际值的占位符的一部分。不要在实际请求中使用花括号。所以像这样:

https://developers.facebook.com/apps/{APPLICATION_ID}/advanced

变成这样的东西,例如:

https://developers.facebook.com/apps/123456/advanced

其中123456是实际的Facebook应用程序ID。

答案 1 :(得分:-1)

  

作为一个无人值守的后台进程,向用户(可能是我)提出任何问题都不是真正的选择。

正如我已经说过的,你只需一次

您获得了非过期的网页访问令牌,将其复制并粘贴到您的应用中 - 从那时起,您的应用就可以在服务器端做任何想要做的事情。

  

我也被告知我不能从我的浏览器做一次性请求获取访问令牌,因为根据定义,这是客户端交互,而不是必要的服务器端流程的一部分。

获取用户访问令牌的服务器端身份验证流程也需要部分参与浏览器。

如果您通过客户端身份验证流获取一个短期令牌并在之后扩展它,或者如果您使用服务器端身份验证流程获得一个长期令牌,则无关紧要。

  

(对我而言,如果RESTful请求来自Web浏览器而不是来自应用程序[...],这似乎很奇怪

Facebook不希望用户将其登录凭据提供给任何第三方。因此,获取用户访问令牌的过程始终必须参与浏览器,用户登录Facebook。

  

因此,如果我可以执行一些手动步骤来获取应用程序发布到Facebook页面的永久访问令牌,那么这些步骤是什么?

获取具有manage_pages权限的长期用户访问令牌。 (或者获得一个短暂的,并扩展它)。然后,使用该长期令牌以文档中描述的方式请求目标页面的页面访问令牌。