Facebook JS SDK Does Not Set fbs_* Cookie in Safari - facebook

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.

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.

Can't Logout of my Facebook OAuth Session without logging User Out of Facebook

Per the SDK, I am using the logout.php with redirect:
https://www.facebook.com/logout.php?confirm=1&next={SOME URL}&access_token={ACCESSTOKEN}
It is logging me out fine, but it's also logging the user out of facebook. Isn't there a way of logging out of my OAuth session without logging out of facebook?
Yes, I ran into this same issue myself. Dont do logout.php or JS SDK's FB.logout(). Rather call the Graph API with an HTTP Delete command to me/permissions. That will kill the access token, remove the app from the user's app listing and maintain their browser's cookie for facebook. You can call it either server side or client side. Here's the client side Javascript SDK way:
FB.api("me/permissions","delete", function(response){/*do something if you want*/})
This is one of the many annoying things about developing on the Facebook platform. The only way to log out via a browser session is to use their javascript logout function or the redirect like you tried but either will also log the user out of Facebook which is very annoying from a users perspective. The problem is you can't access the cookie they set for your app to delete it due to cross-domain restrictions so you are stuck with the limited options Facebook provides. If you are not prompting for offline_access, you could just forget the users access token and it will expire after an hour. Although the problem still exists that the cookie is still set for within that hour.

Behavior of page when loaded into Facebook application tab

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.

facebook canvas app inside iframe redirects and signed request

I am building a facebook canvas app and i am using the signed request parameter provided by facebook to check if the user has already authenticated the app. (by checking the presence of user_id field). If the user_id is not set then I redirect the user to a uthorization page (using top.location in javascript).
The problem is that, in my application I need to make internal redirects and then i canĀ“t get signed request anymore.
Possible solutions:
1). Change the way i check if the user has installed the app . Get the current user (not sure if I need signed request anyway). Then use the graph api to check the permissions).
2). allways use client side redirects. (then I can allways get the signed request and it is also provides better navigation to the user because the top url change.) Not sure about the performance compared with iframe redirects.
What is the best option, in your opintion.
PS: I am using PHP SDK / symfony framework and the javascript sdk.
The most common way to handle this is to set a cookie to carry forward either signed_request or whatever subset of data from it you need, so it is available on all pages. You can do this directly or by using PHP sessions to store the data.
However I am personally of the opinion that cookies are a bad idea within iframe apps. For an alternate approach that may do what you need, have a look at http://www.braintilt.com/fbcookies.php .

How to make a website that functions as a website and a facebook app?

I have a website based game that has login accounts that I want to integrate into facebook (not facebook connect, I want to use an iframe canvas page).
My question is how can I authenticate a user and how can I check if a user is coming from facebook or directly from the site.
I have been playing around with require_login() using the PHP library. My main fear is how can I authenticate that the GET parameters from facebook are indeed from facebook? If I can do that then I can store their facebook session id and Uid in a session as login credentials.
My other worry is that the GET variable may get passed as a reffer to an external link.
Finally... I find in some browsers that with require_login() that it breaks out of the iframe and gets into an eternal look continually adding additional authtoken's to the URL.
Hope someone can help
Yes you can create a app that works independently as well as facebook app. For the facebook you will have to use the facebook's iframe method to work under facebook.
You can verify the request comes from Facebook by verifying the signature in the same way that Facebook checks that API requests come from your application. With the PHP client library you can use the validate_fb_params() method of the Facebook class to do this automatically.
Bear in mind that session key's are temporary so the user will keep needing to authenticate with Facebook through your application otherwise the key expires within the hour. You may also run into a 3rd party cookie issue with Safari if you're hoping to store the session key in a cookie, and you'll need a compact privacy for quite a few other browser/privacy setting combinations as well. Something like:
<?php
header('P3P: CP="CAO PSA OUR"');
?>
in an include would do it.
And yes: the session key may be passed to external sites as in the referrer properties. It's just one of the security flaws that the platform currently has. The only way around that is either to redirect all external clicks through a handler which removes the referrer, or redirect on page load to strip the fb_sig_ss parameter out.