【问题标题】:How to know if my page is running in a facebook iframe or not如何知道我的页面是否在 facebook iframe 中运行
【发布时间】:2011-10-16 10:47:18
【问题描述】:

我目前正在开发一个独立运行的网站,并作为 iframe 上的 facebook 应用程序运行 我想知道在页面加载之前检查我的页面是否在 facebook iframe 中运行的“最佳实践”是什么,以便我可以预设相关的 CSS 和其他变量

谢谢。

【问题讨论】:

    标签: php facebook


    【解决方案1】:
    $signed_request = $_POST['signed_request'];
    
    if(empty($signed_request))
          die('No direct access.');
    

    【讨论】:

      【解决方案2】:

      有几种方法可以解决这个问题。如果您不关心安全性(即您真的只想知道如何格式化页面而不是决定显示哪些内容),那么您最好的选择可能是使用不同的 url 访问 Facebook。例如,如果您的独立站点是 www.mysite.com,您可以将 fb.mysite.com 或 www.mysite.com/fb 配置为指向同一个地方,然后在您的应用设置中使用备用版本。然后,您的服务器代码可以轻松检查正在访问的 url 版本并采取相应措施。当然,您必须小心处理您的链接,以确保它们保持正确的前缀。

      另一种方法是使用所讨论的 signed_request,当它存在时设置一个 cookie(或会话)以指示 Facebook 访问。诀窍是在每个页面的顶部还包含一些 javascript 代码,以检查以确保页面在 iframe 内。如果没有,那么代码会立即重定向回当前页面,并添加一个类似“?clearfb=1”的参数,这将告诉服务器清除 cookie/会话并以外部格式输出页面。

      【讨论】:

      • 我认为您所指的“javascript 代码位”是 window.top==window?
      • 是的,类似于每页顶部的 if (window.location==top.location) window.location='thispage.php?clearfb=1'; 行,但如果服务器当前以 iframe 格式输出。当然还有适当的服务器端代码来检测 clearfb 参数并做出适当的反应。
      • 如果您使用上述不同的 URL 设置,您还可以使用 mod_rewrite 将所有请求路由到同一个实际页面。
      【解决方案3】:

      检查signed_request 是否存在也是一个很好的测试...

      【讨论】:

      • 检查 signed_request 是了解页面在 Facebook 框架内(而不是仅仅在某个 iframe 内)的最佳方式,但请记住它仅在第一次加载时设置。当用户点击指向新页面的链接时,您必须有一些方法来“保留”该设置。
      • 为什么是only set on first load?我找不到对此行为的任何参考。您能否将我们链接到此信息?
      • 我不知道它在任何地方都明确说明,这只是 iframe 设置的工作方式。构建页面框架时,通过将 POST 发送到 canvas url 来填充 iframe,并将 signed_request 作为参数。这是唯一一次 signed_request 将被自动发送。在那之后,Facebook 无法再次发送它,因为 iframe 处于应用程序的控制之下。再次发送 signed_request 的唯一方法是重新加载整个页面(使用 top.location 或类似内容),这实际上是某些人所做的,但绝对不推荐。
      • 是的,top.location 肯定会为您设置另一个 signed_request,再次是的 - 很多人都这样做; 不推荐。可以将签名的请求放在会话变量中或将其存储在 JS 变量中。我的做法是在它存在时立即对其进行解析并将其编织到页面服务器端逻辑中,并且始终避免再次毫无意义地重新加载整个页面。
      • 谢谢大家,但它仍然不能满足我的需要,因为如果我将数据保存在浏览器会话中,那么在我在 facebook iframe 之外打开相同页面后,它仍然使用相同的会话。一定有办法知道这一点......@FloydWilburn
      【解决方案4】:

      这里有一些 php 代码来测试当前页面是否在 facebook iframe 中运行:

      if( strpos( $_SERVER[ 'HTTP_REFERER' ], "apps.facebook.com" ) !== false ){
          // Page is running in Facebook iframe
      }
      

      【讨论】:

      • HTTP_REFERER 由浏览器发送,不应该被认为是准确的或根本不存在。
      • 这是非常真实的 - 邪恶的用户;)
      • 对于只想添加一行 CSS 的我来说,这是最好最简洁的方法。
      • @gio - 如果那是真的所有你想做的,那么我完全同意你的看法。
      • @gio - 查看我的编辑,包含它是明智的。 strpos()函数comes with a warning的返回值
      【解决方案5】:

      唯一真正的检查可以在客户端通过比较window.top==window 是否为真应用程序在iframe 之外运行。

      没有服务器端检查可以确保这一点,因为浏览器不会将有关父框架的信息传递给 HTTP_REFERRER 以外的服务器,这是不可信的。

      如果在 Page Tab CanvasCanvas 上运行,Facebook 会将 signed_request 传递给您的应用程序,但这不是您可以完全信任的东西,因为它也可以被用户模仿。

      更新

      声明这是唯一真正的检查并不意味着您应该使用它!您最好坚持使用基于 signed_request 的解决方案,因为它是 Facebook 与您的应用程序交互的一种方式,用户不打算使用 signed_request 并且它在任何情况下都不应作为查询字符串的一部分传递!如果用户模仿它,可能有问题,在这种情况下我不会费心提供错误的样式。

      【讨论】:

      • 如果进行此检查的唯一原因是不同的 CSS 文件,您可以通过在页面完全加载之前注入正确的 link 标签在客户端加载它们,因为检查 window.top==window 可以在任何情况下工作DOM 加载前的时间事件。
      • 其实signed_request是唯一可以完全信任的方法。我不认为最初的问题真的与安全性有关,因为它特别提到了 CSS 更改,但是说 signed_request 与 HTTP_REFERER 或 javascript 窗口测试属于同一类别是错误的。
      • @Floyd Wilburn,可以信任用户身份而不是确保应用程序在iframe 中运行。当然它是不同的类别,它由您信任的权威机构 - Facebook 验证。更新了我的答案以澄清
      • 嗯,是的,但这部分总是假设的,因为检查页面是否在 any iframe 内是没有意义的,我们显然在谈论在 Facebook iframe。为什么有人会手动将 signed_request 参数发送到 iframe 之外的页面?如果他们想“破解”某些东西,他们可以轻松地将其放入 iframe 中,因此我认为没有理由考虑存在 signed_request 但页面不在 iframe 中的情况。
      • 考虑具有除 self 之外的目标属性的表单,包含当前 signed_request 作为字段之一 - 这种技术在某些情况下可能非常有用(我也将它用于几个应用程序)
      【解决方案6】:

      今天早上我遇到了同样的问题 - 我希望桌面用户通过 facebook 访问我的应用程序,但我希望移动用户能够直接通过 URL 访问应用程序。就像 Floyd Wilburn 所说,通过不同的 URL 访问应用程序的不同版本是一个不错的选择,但我没有使用应用程序的两个副本(难以维护),而是使用 mod_rewrite 将 /facebook 目录重写到应用程序根目录:

      # rewrite both /facebook and / to same place so you
      # can tell if your request came from facebook or from direct URL access :)
      RewriteEngine on
      RewriteBase /
      RewriteCond %{REQUEST_URI} /facebook*
      RewriteRule (.*) /index.php [L]
      

      确保将您的 Facebook 页面标签 URL 设置为位于 /facebook 子目录中。现在,您可以通过浏览器嗅探来查看他们是移动用户还是桌面用户,并且您可以测试请求的 URL 以查看他们是通过 Facebook 还是直接访问应用程序 :)

      让我补充一点,确定客户端类型或接入点没有万无一失的方法 - 两者都可能被知道自己在做什么的人欺骗 - 因此在设计应用的安全性和身份验证机制时要考虑到这一点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多