0

我正在通过以下方式对我的应用程序进行自动化:

// authorize app!
                $('#authApp').click(function(){
                    var oauth_url = 'https://www.facebook.com/dialog/oauth/';
                    oauth_url += '?client_id=#{app.id}';
                    oauth_url += '&redirect_uri=' + encodeURIComponent('https://www.facebook.com/pages/null/#{fbPageId()}/?sk=app_#{app.id}');
                    oauth_url += '&scope=user_likes,user_photos';
                    oauth_url += '&app_data=7B%27game%27%3A+%27key%27%7D';
                    oauth_url += '&state=sbSbsbSb';

如您所见,我将“状态”参数设置为查询字符串的一部分。现在,当用户授权应用程序时,他将被重定向到重定向 url。

但是,在 state 参数中传递的数据不会发布到我的应用程序,也不是我的应用程序 iframe 查询字符串的一部分。我希望在签名请求中找到它,但没有。这是授权后发回的反序列化签名请求

{ algorithm: 'HMAC-SHA256',
  expires: 1348927200,
  issued_at: 1348921162,
  oauth_token: 'AAA...',
  page: { id: '490...', liked: true, admin: false },
  user: { country: 'ec', locale: 'en_US', age: { min: 21 } },
  user_id: '1...' }

我确实看到该状态包含在父页面的查询字符串中。我需要从我的应用程序(在 iframe 中运行)访问该参数。我相信由于同源策略限制,我不能只访问父页面的窗口位置。

我已阅读文档并在线搜索。跨应用程序授权持久化数据需要使用 state 参数完成。但是,没有说明一旦重定向回您的应用程序如何检索该状态参数。

这是来自关于状态参数的facebook 文档:

用于维护请求和回调之间的应用程序状态的唯一字符串。当 Facebook 将用户重定向回您的 redirect_uri 时,此参数的值将包含在响应中。您应该使用它来防止跨站点请求伪造。

我应该从父页面查询字符串中获取状态数据吗?还是我做错了什么?

* 编辑* 我将用户存储到状态参数中的用户请求 ID。例如,A 通过 Facebook 请求邀请 B 参与应用程序。一旦 B 授权应用程序 A 需要得到奖励。所以我需要知道 B 在 A 的邀请下来到了应用程序。因此,我将 requestId 存储在 state 参数中,因此一旦 B 授权了应用程序,我就可以采取适当的措施。

* 编辑 2(解决方案) ** 如果您的 redirect_uri 指向页面标签 URL,那么 facebook 将不会发回状态参数!仅当您重定向到 Canvas URL 时才会发回!!!!!!

4

2 回答 2

1

我应该从父页面查询字符串中获取状态数据吗?

不,不是在画布/页面选项卡应用程序中进行身份验证时。在这种情况下,唯一传递给您的应用程序的查询字符串参数是app_data参数的内容。

但你不需要state参数 - 验证signed_request绝对足够,因为它使用您的应用程序密码签名,只有您和 Facebook 知道。因此,这已经足以防止“被操纵”的请求了。

请参阅https://developers.facebook.com/docs/authentication/canvas/resphttps://developers.facebook.com/docs/authentication/pagetab/了解更多详情。(看看他们怎么不提state参数。)

编辑:

我将用户存储到状态参数中的用户请求 ID。例如,A 通过 Facebook 请求邀请 B 参与应用程序。一旦 B 授权应用程序 A 需要得到奖励。所以我需要知道 B 在 A 的邀请下来到了应用程序。因此,我将 requestId 存储在 state 参数中,因此一旦 B 授权了应用程序,我就可以采取适当的措施。

这是对参数的滥用state......它应该实现完全不同的东西(CSRF保护,正如文档所说)。

虽然这可能适用于您的场景 - 为什么您不使用app_data参数来传输这条信息?这是将信息传输到画布/页面选项卡应用程序的指定方式。

于 2012-09-29T15:43:09.093 回答
1

您引用的 Facebook 文档有点混乱。你应该对 state 参数做的唯一一件事是确保你不是 CSRF 的受害者。 Facebook 的服务器端身份验证流程在 PHP 中给出了一个示例。简而言之,您应该将状态值存储在会话中,然后验证会话值是否与 Facebook 在请求中传回给您的值相同。他们的 PHP 示例中的关键行是:

if($_SESSION['state'] && ($_SESSION['state'] === $_REQUEST['state'])) {
   // Continue with application logic here because state matches.
   // Otherwise, exit immediately because you're a victim of CSRF!

所以回到你的问题。从您的重定向 URL 和您收到的响应中,很明显您的应用位于 Facebook 页面选项卡上。请参阅页面选项卡的身份验证流程,了解您应该如何执行此操作。请注意,他们没有在步骤 2 中使用 state 参数,并且在页面选项卡身份验证流程中从未提及 state 参数。因此,即使您想将 state 参数用于预期用途之外的其他用途,您也不走运。

根据您的编辑,我建议您查看有关 requests 的文档。请注意,单击请求的用户将被重定向到您的画布应用程序,而不是页面选项卡。“画布 URL 还将包含一个额外的 GET 参数 request_ids,它是一个逗号分隔的列表,由用户尝试操作的请求 ID 分隔列表。” 因此,您无需自己尝试这样做。

于 2012-09-29T15:54:03.667 回答