【发布时间】:2011-10-16 10:47:18
【问题描述】:
我目前正在开发一个独立运行的网站,并作为 iframe 上的 facebook 应用程序运行 我想知道在页面加载之前检查我的页面是否在 facebook iframe 中运行的“最佳实践”是什么,以便我可以预设相关的 CSS 和其他变量
谢谢。
【问题讨论】:
我目前正在开发一个独立运行的网站,并作为 iframe 上的 facebook 应用程序运行 我想知道在页面加载之前检查我的页面是否在 facebook iframe 中运行的“最佳实践”是什么,以便我可以预设相关的 CSS 和其他变量
谢谢。
【问题讨论】:
$signed_request = $_POST['signed_request'];
if(empty($signed_request))
die('No direct access.');
【讨论】:
有几种方法可以解决这个问题。如果您不关心安全性(即您真的只想知道如何格式化页面而不是决定显示哪些内容),那么您最好的选择可能是使用不同的 url 访问 Facebook。例如,如果您的独立站点是 www.mysite.com,您可以将 fb.mysite.com 或 www.mysite.com/fb 配置为指向同一个地方,然后在您的应用设置中使用备用版本。然后,您的服务器代码可以轻松检查正在访问的 url 版本并采取相应措施。当然,您必须小心处理您的链接,以确保它们保持正确的前缀。
另一种方法是使用所讨论的 signed_request,当它存在时设置一个 cookie(或会话)以指示 Facebook 访问。诀窍是在每个页面的顶部还包含一些 javascript 代码,以检查以确保页面在 iframe 内。如果没有,那么代码会立即重定向回当前页面,并添加一个类似“?clearfb=1”的参数,这将告诉服务器清除 cookie/会话并以外部格式输出页面。
【讨论】:
if (window.location==top.location) window.location='thispage.php?clearfb=1'; 行,但仅如果服务器当前以 iframe 格式输出。当然还有适当的服务器端代码来检测 clearfb 参数并做出适当的反应。
检查signed_request 是否存在也是一个很好的测试...
【讨论】:
only set on first load?我找不到对此行为的任何参考。您能否将我们链接到此信息?
top.location 肯定会为您设置另一个 signed_request,再次是的 - 很多人都这样做; 不推荐。可以将签名的请求放在会话变量中或将其存储在 JS 变量中。我的做法是在它存在时立即对其进行解析并将其编织到页面服务器端逻辑中,并且始终避免再次毫无意义地重新加载整个页面。
这里有一些 php 代码来测试当前页面是否在 facebook iframe 中运行:
if( strpos( $_SERVER[ 'HTTP_REFERER' ], "apps.facebook.com" ) !== false ){
// Page is running in Facebook iframe
}
【讨论】:
strpos()函数comes with a warning的返回值
唯一真正的检查可以在客户端通过比较window.top==window 是否为真应用程序在iframe 之外运行。
没有服务器端检查可以确保这一点,因为浏览器不会将有关父框架的信息传递给 HTTP_REFERRER 以外的服务器,这是不可信的。
如果在 Page Tab Canvas 的 Canvas 上运行,Facebook 会将 signed_request 传递给您的应用程序,但这不是您可以完全信任的东西,因为它也可以被用户模仿。
更新:
声明这是唯一真正的检查并不意味着您应该使用它!您最好坚持使用基于 signed_request 的解决方案,因为它是 Facebook 与您的应用程序交互的一种方式,用户不打算使用 signed_request 并且它在任何情况下都不应作为查询字符串的一部分传递!如果用户模仿它,可能有问题,在这种情况下我不会费心提供错误的样式。
【讨论】:
link 标签在客户端加载它们,因为检查 window.top==window 可以在任何情况下工作DOM 加载前的时间事件。
iframe 中运行。当然它是不同的类别,它由您信任的权威机构 - Facebook 验证。更新了我的答案以澄清
今天早上我遇到了同样的问题 - 我希望桌面用户通过 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 还是直接访问应用程序 :)
让我补充一点,确定客户端类型或接入点没有万无一失的方法 - 两者都可能被知道自己在做什么的人欺骗 - 因此在设计应用的安全性和身份验证机制时要考虑到这一点。
【讨论】: