2011-10-16 70 views

回答

5

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

的另一种方法是使用如signed_request所讨论的,设置cookie(或会话)时,它的存在是为了表示一个网站的访问。这里的技巧还包括在每个页面的顶部添加一些javascript代码,以检查页面是否在iframe中。如果不是,那么代码会立即重新引导回当前页面,并添加一个类似“?clearfb = 1”的参数,这将告诉服务器清除cookie /会话并以外部格式输出页面。

+0

我认为你引用的“javascript代码位”是window.top ==窗口? –

+3

是,沿着线的东西'如果(window.location的== top.location)了window.location = 'thispage.php clearfb = 1?';'在每个页面的顶部,但只有* *如果服务器目前以iframe格式输出。当然还有合适的服务器端代码来检测clearfb参数并做出适当的反应。 –

+0

@FloydWilburn,如果'window!= window.top'访问'top.location'时会遇到安全警告,如果域由于跨域策略而不同。 –

2

下面是一些PHP代码来测试,如果当前页面是Facebook的iframe中运行:

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

HTTP_REFERER是由浏览器发送的,不应该被信任是准确的或存在一样。 – 472084

+0

这是非常真实的 - 邪恶的用户;) – Lix

+0

这是对我来说最好和简洁的方法,只想添加一行CSS。 –

3

检查,看是否有signed_request存在也将是一个很好的考验......

+2

检查signed_request是知道该页面在Facebook框架内的最佳方式(而不仅仅是在某个iframe内部),但请记住它仅在第一次加载时设置。当用户跟随​​新页面的链接时,您必须有一些方法来“坚持”设置。 –

+0

为什么'只在第一次加载时设置?我无法找到任何有关此行为的参考。 你能把我们链接到这个信息吗? – Lix

+1

我不知道它在任何地方都有明确说明,它只是iframe设置的工作方式。构建页面框架时,通过发送POST到带有signed_request参数的画布网址来填充iframe。这是signed_request自动发送的唯一时间。之后,Facebook无法再发送它,因为iframe然后在应用程序的控制之下。再次发送signed_request的唯一方法是重新加载整个页面(使用top.location或类似的),这实际上是一些人做的,但绝对不推荐。 –

6
$signed_request = $_POST['signed_request']; 

if(empty($signed_request)) 
     die('No direct access.'); 
1

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

没有服务器端检查,可以保证这一点,因为浏览器未通过关于父帧比其他HTTP_REFERRER服务器不能被信任的信息。

Facebook的传递signed_request到您的应用程序,如果在页面标签画布帆布运行,但是这是不是你可以完全信任,因为它可以通过用户也可以模仿。

更新

,这是唯一真正的检查并不意味着你应该使用它的语句!你最好坚持signed_request基础的解决方案,因为它是一个Facebook的方式与你的程式互动,用户不打算使用signed_request,它不应该在任何条件下被作为查询字符串的一部分过去了!如果用户模仿它,有可能是错误的,那么在这种情况下我就不会提供错误的样式。

+0

如果执行此检查的唯一原因是不同的CSS文件,您可以通过在页面完全加载之前注入正确的'link'标签来加载客户端的em,因为检查window.top == window'将在任何时间事件在DOM加载之前。 –

+0

其实signed_request是可以完全信任的* only *方法。我不认为最初的问题是关于安全性的,因为它特别提到了CSS更改,但是说signed_request与HTTP_REFERER或javascript窗口测试属于同一类别是错误的。 –

+0

@Floyd Wilburn,可以信任用户身份,而不是确保应用程序在'iframe'中运行。确定它是不同的类别,它是由您信任的权威机构验证的 - Facebook。更新我的回答澄清 –

0

我今天早上遇到了同样的问题 - 我希望桌面用户可以通过Facebook访问我的应用程序,但我想移动用户可以直接通过URL来访问应用程序。就像弗洛伊德威尔伯恩说,通过不同的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或直接:)应用

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

相关问题