2011-10-16 15 views
9

Attualmente sto sviluppando un sito che funziona standalone e come applicazione Facebook su un iframe Mi chiedevo che cosa whold essere "best practice" per controllare se il mio la pagina viene eseguita in un iframe di Facebook prima che la pagina venga caricata, in modo da poter preimpostare il codice CSS pertinente e altre variabiliCome sapere se la mia pagina è in esecuzione in un iframe facebook o no

Grazie.

risposta

5

Ci sono un paio di modi per avvicinarsi a questo. Se non sei preoccupato per la sicurezza (cioè vuoi solo sapere come formattare la pagina piuttosto che decidere quali contenuti mostrare), allora la tua migliore possibilità potrebbe essere quella di usare un URL distinto per l'accesso a Facebook. Ad esempio, se il tuo sito standalone è www.mysite.com, puoi configurare fb.mysite.com o www.mysite.com/fb in modo che puntino allo stesso posto, quindi utilizzare la versione alternativa nelle impostazioni dell'app. Il tuo codice server può quindi facilmente verificare quale versione dell'url è in accesso e agire di conseguenza. Ovviamente devi prenderti cura dei tuoi collegamenti per assicurarti che mantengano il prefisso corretto.

Un altro modo è utilizzare signed_request come discusso, impostando un cookie (o sessione) quando è presente per indicare un accesso Facebook. Il trucco è quello di includere anche un po 'di codice javascript nella parte superiore di ogni pagina che controlla per assicurarsi che la pagina sia all'interno di un iframe. In caso contrario, il codice reindirizza immediatamente alla pagina corrente con un parametro aggiunto come "? Clearfb = 1" che comunica al server di cancellare il cookie/sessione e di visualizzare la pagina in formato esterno.

+0

Considero che il "bit di codice javascript" a cui fai riferimento è window.top == window? –

+3

Sì, qualcosa sulla falsariga di 'if (window.location == top.location) window.location = 'thispage.php? Clearfb = 1';' all'inizio di ogni pagina, ma * solo * se il server è attualmente in uscita in formato iframe. E naturalmente il codice lato server appropriato per rilevare il parametro clearfb e reagire in modo appropriato. –

+0

@FloydWilburn, BTW accede a 'top.location' se' window! = Window.top' aumenterà l'avviso di sicurezza se i domini differiscono a causa della politica dei domini incrociati. –

2

Ecco il codice php per verificare se la pagina corrente è in esecuzione all'interno di un iframe facebook:

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

HTTP_REFERER viene inviato dal browser e non dovrebbe essere considerato attendibile o non esiste. – 472084

+0

questo è molto vero - utenti malvagi;) – Lix

+0

Questo è l'approccio migliore e conciso per me che voglio solo aggiungere una riga di CSS. –

3

controllo per vedere se un signed_request è presente sarebbe anche un buon test ...

+2

Controllare la richiesta firmata è il modo migliore per sapere che la pagina si trova all'interno del framework di Facebook (al contrario di essere semplicemente all'interno di un iframe da qualche parte) ma ricorda che è impostata solo sul primo caricamento. Dovrai avere un modo per "persistere" l'impostazione mentre l'utente segue i collegamenti alle nuove pagine. –

+0

perché "impostato solo al primo caricamento"? Non riesco a trovare alcun riferimento a questo comportamento. Potete per favore collegarci a queste informazioni? – Lix

+1

Non so che sia esplicitamente dichiarato ovunque, è solo il modo in cui funziona la configurazione dell'iframe. Quando viene costruita la struttura della pagina, l'iframe viene popolato inviando un POST all'URL della tela con signed_request come parametro. Questa è l'unica volta in cui la richiesta firmata verrà inviata automaticamente. Dopodiché, Facebook non ha modo di inviarlo di nuovo, poiché l'iframe è quindi sotto il controllo dell'app. L'unico modo per ottenere nuovamente signed_request inviato è quello di ricaricare l'intera pagina (utilizzando top.location o simile) che è in effetti ciò che alcune persone fanno, ma sicuramente non è raccomandato. –

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

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

L'unico controllo reale per questo può essere eseguito sul lato client confrontando window.top==window se è vero L'applicazione viene eseguita al di fuori di un iframe.

Non esiste alcun controllo sul lato server che possa garantire ciò poiché i browser non trasmettono informazioni sui frame padre al server diverso da HTTP_REFERRER che non può essere considerato attendibile.

Facebook passando signed_request alla vostra applicazione, se in esecuzione su Tela di Pagina Tab Tela ma questo non è qualcosa che si può fidare completamente dal momento che può essere imitato dall'utente troppo.

Aggiornamento:

L'affermazione che questo è l'unico vero controllo non significa che si dovrebbe usare! È meglio attenersi alla soluzione basata su signed_request, dal momento che è un modo in cui Facebook interagisce con le tue app, gli utenti non sono destinati a utilizzare signed_request e lo non dovrebbe in nessuna condizione essere passato come parte della stringa di query! Se l'utente lo imita, probabilmente qualcosa non va, non mi preoccuperei di fornire uno stile sbagliato in quel caso.

+0

se l'unico motivo per fare questo controllo è diverso con i file CSS, è possibile caricarli sul lato client inserendo i tag 'link' corretti prima che la pagina sia completamente caricata poiché il controllo di' window.top == window' funzionerà in qualsiasi momento prima che il DOM sia caricato. –

+0

In realtà signed_request è il metodo * only * che può essere completamente affidabile. Non penso che la domanda iniziale riguardi realmente la sicurezza perché menziona in modo specifico le modifiche ai CSS, ma è sbagliato affermare che signed_request si trova nella stessa categoria dei test di finestra HTTP_REFERER o javascript. –

+0

@Floyd Wilburn, può essere considerato attendibile per l'identità dell'utente per non garantire che l'app sia in esecuzione in "iframe". Certo è una categoria diversa, è verificata dall'autorità di cui ti fidi - Facebook. Aggiornato la mia risposta per chiarire –

0

Mi sono imbattuto in questa stessa domanda questa mattina: voglio che gli utenti desktop accedano alla mia app tramite Facebook ma voglio che gli utenti mobili siano in grado di accedere all'app direttamente tramite URL.Come ha detto Floyd Wilburn, l'accesso alle diverse versioni dell'app tramite diversi URL è una buona opzione, ma invece di avere due copie dell'app (difficile da mantenere) ho usato mod_rewrite per riscrivere la directory/facebook nella root dell'app:

# 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] 

Assicurarsi di impostare l'URL della scheda di pagina di Facebook per atterrare nella sottodirectory/facebook. Ora puoi fare il browser sniff per vedere se sono utenti mobili o desktop e puoi testare l'URL richiesto per vedere se accedono all'app tramite Facebook o direttamente :)

Lasciami aggiungere che c'è Niente modo infallibile per determinare il tipo di client o il punto di accesso: entrambi possono essere falsificati da qualcuno che sa cosa stanno facendo, quindi prendilo in considerazione quando progetti i meccanismi di sicurezza e autenticazione della tua app.

Problemi correlati