Behavior of page when loaded into Facebook application tab - facebook

When a user visits my site "www.mysite.com" I set a cookie for that specific user.
Next the user goes to Facebook, lands on an application tab and clicks the like button. An external page "www.mysite.com/facebooktab.html" is loaded into the Facebook canvas.
1. Now, do I have access from facebooktab.html to the cookie I set on www.mysite.com earlier?
2. Does the page loaded into Facebook show the same behaviour as when I would just visit www.mysite.com/facebooktab.html in my browser, except that when the page is loaded within Facebook I have some additional user properties available to me (since user is logged in in Facebook)?

The critical difference between the two scenarios is that when your page is loaded directly, the cookies you set/read are "first party" cookies; when your page is loaded inside the Facebook framework, the cookies become "third party". Each browser has its own set of rules, but they all apply different policies to third-party cookies versus first party cookies. You mentioned you are initially setting the cookie directly on your website (first-party mode), and then only reading it when the page is inside Facebook (third-party mode). Most browsers will allow that with no restrictions, as they only apply stricter third-party policies to the writing of cookies and not reading. The exception is Firefox, which lumps reading and writing permissions together. If a Firefox user has cleared the "Accept third-party cookies" box in their configuration, your page on Facebook will not be able to read the cookie you set earlier even though it was set directly on your website.

Related

Facebook Login link redirects straight back to my application without ever showing login dialog

I am attempting to implement a simple Facebook login flow for a web application using HTTP redirects, as detailed at https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2.
For the purposes of making this question generic, let's say the application URL is www.example.com/app.php. On the application page, there is a link which directs users to Facebook's OAuth endpoint, where ideally:
they log in to Facebook (if not already logged in) and approve my application permission to access their public profile
they are then redirected back to my application's URL along with some extra parameters appended (e.g. www.example.com/app.php?code=...&access_token=... if the login was successful, or www.example.com/app.php?error_reason=...&error=...&error_description=... if login/app approval was unsuccessful)
The Facebook OAuth endpoint is:
www.facebook.com/dialog/oauth?client_id=12345&redirect_uri=www.xyz.com/app.php
where I have filled in the client_id and redirect_uri parameters with my application's ID and my application's URL respectively.
What actually happens whenever I access the link is that it immediately redirects back to my application's homepage - without ever showing a login dialog of any kind. This happens with Firefox and with Chrome - both when I am logged in to Facebook and when I am not, in normal sessions and in incognito sessions with no plugins enabled. From the browser inspector, I can see that the Facebook OAuth page is definitely requested but is straight away 302 redirecting to my application page with just a code parameter appended.
www.example.com/app.php?code=...
This also happens when the Facebook OAuth link is accessed from pages other than my application's URL (e.g. if I click the link from www.example.com/other_page.htm).
I am unsure what I am doing wrong here; the application URL (www.example.com/app.php) is approved on my app dashboard in as many places as I could find, and changing the request_uri parameter to any other URL results in an error page. I have also tried urlencode()ing my application URL before passing it in the request_uri parameter, but the result remains the same. I don't know what to try next as as far as I can tell I have followed Facebook's manual login guide as closely as possible.

Facebook login with multiple domains

I know that facebook allow me to specify multiple domains for my app.
But in the "Website with Facebook Login" i can only specify one url.
Is it possible for me, to authenticate users on domain.se, domain.dk and domain.net with the same App ? Or should i still create one app, for each domain ?
It is technically possible to use Facebook Connect on multiple domains, there are some limits (5 domains max).
So the key to doing this is adding all domains in the App Domain field under your app settings.
The PROBLEM, however, is that Facebook only lets you add domains that are derived from your Canvas URL or Site or Page tag URLs, so if you try to enter anything else you get an error that looks like this:
The SOLUTION is to create App on Facebook, Website, and Facebook Tab using the ADD PLATFORM button and then put in URLs that point to your other domains. Here is an example of what I mean:
If you use a unique domain for each field you can max out with 5 different domains. I have tested this technique with up to 3 domains, but i think it should work for all 5.
Note: Facebook admin features change from time to time, so all of this is subject to change
As long as you listed all the desired App Domains in application settings you should be able to authenticate users on any of them.
"Website with Facebook Login" is really only intended to be used as link to your site/application.
Update 2 (July 2016):
App domains must match the domain of the Secure Canvas URL, Mobile Site URL, Unity Binary URL, Site URL or Secure Page Tab URL.
Update (December 2013):
At the time of writing original answer it was possible to list any domains in application settings but from that time the UI of Application Settings (as well as way of handling Application Domains) changed at least couple of times, at some point you could only list domains that derive from one of application's canvas pages.
As of December 2013 it is possible (again) to list domains that do not derive from application canvas URL.
Assuming your domains are being served by the same web server and you have access to that web server, you can use the manual login procedure: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow to login from as many domains as you wish.
Assume your domains are site1.com,site2.com.... Instead of using the Facebook javascript API, you will simply place a plain old Log In with Facebook button on each site which will redirect the browser to the facebook login page as described in the above article. In the state variable you can specify a code which indicates which of your sites is requesting a login. In the redirect you will use a single service domain which you assign to your web server (e.g. fb.mywebserver.com) and which you specify as the verified redirect url in the facebook login settings page. All the sites will redirect to this same url, avoiding the problem of supporting multiple domains.
Once the user has logged in, the browser will redirect to fb.mywebserver.com and pass it the state, which tells you which site is requesting login and a code which you can use on the back end to retrieve the user's info using the Facebook graph apis. You store this info with a uid in your data store then using the info in state, you redirect to to the appropriate site including a parameter that indicates a Facebook login (e.g. site1.com?fbc={some uid}). The browser will obediently then call site1.com?fbc... Your web server will receive this request and detect the fbc parameter which tells it to associate the corresponding Facebook logged in user with this site. It can then retrieve the logged in users info using the uid and, for example, return a session cookie for this user along with the page. If you generate the page on the server you can, of course, also include a welcome "user" or alternatively, your client code can do an ajax call to retrieve that information.
From the user's standpoint they press the Login with Facebook button, are redirected to a Facebook login page where they login and then are redirected back to your site in a logged in state. Not quite as nice as having the login popup but likely acceptable.
A similar process can be used for google logins as well
Best thing I've found to do in the development/production scenario is add a "Test App", then add a platform for your development web site - as you have to provide where the "page tab url" lives if you use that as a platform.
Facebook requires your "page url" to be live / accessible if you need to apply for status or permission review.
This got me around the "login in development" / "login in production" scenario.

Shibboleth and Autologin

I have used Shibboleth with manual login, meaning the user clicks the login link on a website which opens the external page where the Shibboleth login page is. Once authenticated it redirects them back to the original site to a Shibboleth enabled page.
My question is once logged in, and they go to another site, how can I authenticate them in automatically since they already have a Shibboleth session from the first site. Do they have to click an action like the first site which in turn will autologin them in with some implicit redirects the user doesn't see, or can I do this without the user clicking a login link without doing a check on every page load.
You can check for the presence of one of Shibboleth's headers, for example Shib_Authentication_Instant, and redirect if that's not present. You can do that on the server level rather than in your application logic, using, for example, mod_shib for Apache.
If you want to show "public content" and additional "member content", things get trickier. I guess you could have a landing page that requests some Shib-protected resource (1x1 invisible GIF with nonce in a query parameter, something AJAXy, whatever):
If your user is already Shib-authenticated, you can see that the resource is being loaded. (Otherwise, he'll be stuck in an invisible login dialog for that resource, which shouldn't matter, and you store that he's not authenticable in the session. This is not security-critical: if the user removes it, he'll go through the gif procedure again, and member content should depend on the headers that your shibbolized web server inserts for you anyway.)
But this is a crude hack, and usability depends on a "good" timeout for the marker gif request.

Access-code renewal in an IFRAME

I have an iframe where I display some of the user's Facebook information. When my server generates the content for the iframe, it checks for responses from Facebook indicating that the access-code has expired, and sets up the re-auth sequence to occur inside the iframe, where it will be the least noticeable to the user. If, however, the server detects that the user is not logged in, it will bounce out to a new browser window to lead the user through sign-up.
Lately, I've noticed my iframe tends to go blank. The issue appears to be that occasionally the Facebook APIs will report an access-code as expired when, in fact, the user is not even signed in. Attempting to renew the access-code causes Facebook to redirect to the login page. But the login page is served with 'X-Frame-Options:DENY' Header, so the browser just refuses to display anything in my iframe. I don't have any control over this process once I invoke the URL to renew the access code, and since the content in the iframe is on a different domain, the hosting page can't even detect when this situation has happened.
Anybody know of a solution to this? Ideally, the Facebook APIs would more accurately report on expired access tokens, but failing that, it would be nice if I could set the login page to be redirected to a new window.

Facebook JS SDK Does Not Set fbs_* Cookie in Safari

I've read a few posts about how to fix this, to sum it up:
Manually create the fbs_* cookie during the first POST request to your app
Add a "Start App" link, when the user clicks it Safari lets you set cookies (http://lightyearsoftware.com/2009/11/on-the-pain-of-developing-for-facebook/)
Create and submit a form client side (http://anantgarg.com/2010/02/18/cross-domain-cookies-in-safari/)
None of that seems to work, I'm questioning whether or not that information is still valid (I'm on Safari 5.0.5). I need to use the fbs cookie to properly authenticate the user on the server side, and this works on every other browser. I can't set any cookies on the initial POST request, and the client-side form submit doesn't work either. Does Safari not let you set third party cookies even on a POST anymore?
The reason cookies are rejected is a default "third party cookies" policy in Safari.
To properly authenticate the user you better stay away from manual usage of fbs_* cookies placed by Facebook's JS (or any other) SDK and use FB.getSession / FB.getAuthResponse and/or FB.getLoginStatus from JS SDK. On the server side you can use signed_request parameter passed to all Canvas and Page Profile Tab applications.