So I'm building my app around facebook oauth, and was hoping to use the fbsr_ token to identify logged-in users (so that the facebook-js stuff stays in sync with my site).
Unfortunately, it appears that these fbsr_* cookies are set to expire within a day. Which means if the user comes to my site a day later, they have no cookie and are shown a logged-out experience.
The facebook-js then runs, recognizes them, creates the fbsr_* cookie, and gives me a callback. I can choose to do a hard page refresh (rather jarring), or try to do fancy in-place ajax updating (tons of complex code, still slightly jarring). Is there a reason these cookies don't have a longer expiration so the user stays logged-in seamlessly? Most websites allow you to "remember me" when you log in to avoid constant cookie expirations, so I'd rather not have my facebook-enabled website keep logging me out.
Is there anything I can do about this? I suspect I can probably switch to serverside-oauth where I manage identity and cookie expiration myself (yes?). But it seems strange that clientside-oauth would have such a limitation, so I'm hoping I'm missing something.
Is there anything I can do about this?
No, not really.
The only way to determine, if a user is currently logged in to Facebook, is to look at the cookie set for the domain facebook.com.
The JS SDK is capable of doing that, because it runs client-side, and can make a cross-domain request to check if these cookies are set.
But there is no way to check for those cookies server-side from your domain – your server only has access to cookies set for your own domain.
I suspect I can probably switch to serverside-oauth where I manage identity and cookie expiration myself (yes?)
If your set your own cookies on your domain, you are implementing your own login system.
And even if you “fake” the cookies that the JS SDK sets under your domain, it would not bring the same results.
There might be a cookie on your domain, that says, “yes, user XYZ is logged in to Facebook” – but that would not have to be the case. I could have logged out of Facebook in the meantime, and your cookies would not reflect that at all. So whatever you’ll try to do next, like f.e. posting something on my behalf from your app, will most likely fail, because you only think I was still logged in to Facebook, but in reality you do not have a valid access token for me any more, since I am not really logged into Facebook.
The facebook-js then runs, recognizes them, creates the fbsr_* cookie, and gives me a callback. I can choose to do a hard page refresh (rather jarring), or try to do fancy in-place ajax updating (tons of complex code, still slightly jarring).
Those are your only viable options.
Related
Are there security concerns with displaying an access token my OAuth 2.0 app has obtained? Maybe not necessarily display, but even echo it to a website's source code where it's essentially "findable" by the user. Assume everything is HTTPS.
Example: I have a website where I want to allow people to log in with Facebook. Once they log in, I get an FB API access token back from an identity provider or the Facebook PHP SDK. This token is tied to the user that just logged in. I want to make the user feel at home by displaying their profile picture, is it safe to render some HTML similar to the following?
<img src='https://graph.facebook.com/me/picture?access_token=USERS_ACCESS_TOKEN'>
Edit:
I know there are other options for displaying a profile picture, I'm not necessarily asking for a better way to do that. I'm more interested in the security that needs to be taken with these access tokens. Most of the resources I've seen don't seem to mention anything about it.
The access token should have a minimal set of permissions associated with it, i.e. just enough to actually display the users picture. In that case there's no increased risk wrt. XSS attacks since each solution to display the picture would involve the same risks in the case that an attacker manages to steal the session cookie and/or the token.
Only when the access token has additional permissions associated with it that are not used as a part of your front-end it would be a less preferred from a security standpoint to present it in the front-end.
Well, if the OAuth token is tied to the user session then there is nothing simpler for the attacker to steal users cookie (for instance by XSS) and use it together with the access token to make some actions on his FB on behalf of his account in your app. I would say rule of thumb in security related stuff is to disclose only the information you really have to and nothing else.
Ahh i see what you're doing. Instead of the oauth token do this: http://graph.facebook.com/1477079525902964/picture and ta-da
All I want is to find at least one working solution for this simple thing.
I want to determine what facebook user making request to my FB canvas application. I also want the mechanism to take into account cases when user logs off or re-logs on.
I've really broken my head on that :(
Ways i've already tried:
1) Getting and parsing signed_request param while user's initial request to the application. Cons: the canvas main page is the only place to get it. I never know what user is doing next actions.
2) Using fbsr cookie. Cons: sometimes i get error when trying to exchange cookie's code to user's access token. I still cant reproduce it, it just occurs. Btw, does it work at your?
3) Handling every get/post request at client side and adding user's access token being retrieved by JS SDK to the request. Doesnt seem to be a good way.
Well, that's it. What im doing wrong? Will be thankfull a lot for any working solution.
1) Getting and parsing signed_request param while user's initial request to the application. Cons: the canvas main page is the only place to get it. I never know what user is doing next actions.
Well then just put the parsed signed request into the session …
That’s what I usually do – every time Facebook::getSignedRequest results in something other then null, I write it into my session (so I don’t miss if it gets updated, f.e. by the user liking the page).
My scenario is somewhat like this: A user logs into my website with his FB credentials. I capture his ID and the FB access token (say, a long-lived access token). He exits my website, and returns back later. However, this time, his browser has FB open with a different ID. Would I be able to load facebook details of this old id (with which he had registered on my site) using the stored access tokens? Is it possible, or would it result in a clash between the old and the existing FB id?
Correct me if I'm wrong, but he/she should stay logged into your website, regaurdless if his authID changes.
First of all, why would you want to do that? Since Facebook does not allow multiple user accounts for one and the same person, the only case where this would normally come into play is when another user is using my computer/browser – and why would I want you to read my info while that other person is using my device …?
Second of all, as long as the first user is still considered logged in to your site, it makes not much difference. But lets say some client-side method is called that updates the cookie information, then that’s where trouble might start. You might still be able to read the old user’s info, since you have his valid access token – but you’d have to use that token in your requests explicitly, and also address the account specifically, since the Graph API’s /me would point to the new user.
But as I said, I can hardly imagine a real, practical use case here …
I have developed a facebook app (iframe). It works fine. But when user disables Third-Part Cookies in browser, the app goes into infinite redirection loop.
Please let me know if you need more info to help me out.
Are you sure you really need cookies? If so, unfortunately there is not really much you can do about this. If your app requires cookies to work, you're going to need the user to support third-party cookies. Check to make sure, though, that you're sending a P3P header. Some browsers require a valid P3P header in order to allow third-party iframe cookies at all, even if third-party cookies are enabled.
Exceptions:
If you only need one request, you can just rely on signed_request.
You could try using URL-based sessions instead of cookie-based sessions. PHP has some amount of built-in support for this, but with other languages/frameworks you might have to put some more work in.
I'm guessing that what you are doing is trying to redirect users to the OAuth dialog, and then that dialog is sending users back to your page, right? For that first request after an OAuth dialog, you should try to get authentication information out of the signed_request. Then you might want to store this in a server-side session and pass the ID of that around in either a cookie or query parameters. I believe the PHP and Python SDKs both do something like this. As I said above, if cookies don't work, you will need to figure out another way to persist state as users move around your application.
My honest recommendation? Try to detect if a user's browser does not allow setting a third-party cookie, and if it doesn't, then just throw up an error page explaining that their security settings will not let them use cool apps like yours.
if third party cookie is disable, session will not going to work as well as the session_id is store as cookie as well.
I have a Facebook-App with a form to submit. I only want the users to be able to fill out the form once. What I would like to do is set a cookie + I was wondering if I can set something like a FB App-Cookie/token, that tells Javascript that I can't submit again?
Your app is just a regular iframe, so you can set cookies just as easily as if it were a normal website, outside of Facebook.
Don't forget, though, that you should never trust user input, so you will want to validate against multiple entries on the server as well — either by checking their Facebook user ID or some unique piece of information from your form (like the user's email address, for example).
But yes, you can easily set a cookie from the iframe. You should test to make sure that browsers aren't blocking it as a third-party cookie, though. You can test that easily enough by setting Firefox's preferences to disallow third-party cookies and so on.
Hope this helps!