Roy Toledo
Roy Toledo

Reputation: 643

How to know if my page is running in a facebook iframe or not

I'm currently developing a site which runs standalone and as a facebook app on an iframe I was wondering what whold be "best practice" for checking if my page is ran in a facebook iframe before the page loads so I can preset the relevant CSS and other variables

Thanks.

Upvotes: 9

Views: 8844

Answers (6)

Lix
Lix

Reputation: 47986

Here is some php code to test if the current page is running inside a facebook iframe :

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

Upvotes: 2

siliconrockstar
siliconrockstar

Reputation: 3664

I ran into this same question this morning - I want desktop users to access my app through facebook but I want mobile users to be able to access the app directly via URL. Like Floyd Wilburn said, accessing the different versions of the app through different URLs is a good option, but instead of having two copies of the app (hard to maintain) I used mod_rewrite to rewrite the /facebook directory to the app root:

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

Be sure to set your Facebook page tab URL to land in the /facebook subdirectory. Now, you can browser sniff to see if they're a mobile or desktop user, and you can test the requested URL to see if they're accessing the app through Facebook or directly :)

Let me add that there is NO foolproof way to determine either the client type or access point - both can be spoofed by someone who knows what they're doing - so take this into consideration when designing your app's security and authentication mechanisms.

Upvotes: 0

Juicy Scripter
Juicy Scripter

Reputation: 25928

The only real check for this can be done on client-side by comparing window.top==window if it's true Application is run outside of an iframe.

There is no server side check that can ensure this since browsers not passing information about parent frames to server other than HTTP_REFERRER which cannot be trusted.

Facebook passing signed_request to your application if running on Canvas of Page Tab Canvas but this isn't something you can fully trust since it can be mimicked by user too.

Update:

The statement that this is the only real check doesn't mean you should use it! You better stick to signed_request based solution, since it's a way Facebook interact with your apps, users are not intended to use signed_request and it should not under any conditions be passed as Part of query string! If user mimicking it, something is probably wrong, I wouln't bother providing wrong styling in that case.

Upvotes: 1

Floyd Wilburn
Floyd Wilburn

Reputation: 1842

There are a couple of ways to approach this. If you're not concerned about security (i.e. you really only want to know how to format the page rather than deciding what content to show) then your best bet may be to use a distinct url for Facebook access. For example if your standalone site is www.mysite.com you can configure fb.mysite.com or www.mysite.com/fb to point to the same place, then use the alternate version in your app settings. Your server code can then easily check which url version is being accessed and act accordingly. Of course you have to take some care with your links to make sure they maintain the correct prefix.

Another way is to use signed_request as discussed, setting a cookie (or session) when it is present to indicate a Facebook access. The trick there is to also include a bit of javascript code at the top of each page that checks to make sure the page is within an iframe. If not, then the code immediately redirects back to the current page with a parameter added like "?clearfb=1" which will tell the server to clear the cookie/session and output the page in external format.

Upvotes: 5

Dejan Marjanović
Dejan Marjanović

Reputation: 19380

$signed_request = $_POST['signed_request'];

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

Upvotes: 6

Lix
Lix

Reputation: 47986

checking to see if a signed_request is present would also be a good test...

Upvotes: 3

Related Questions