2011-10-16 107 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或直接:)應用

讓我補充一點,有沒有萬無一失的方式來確定客戶端類型或訪問點 - 兩者都可能被知道自己在做什麼的人欺騙 - 因此在設計應用程序的安全和身份驗證機制時應考慮到這一點。

相關問題