TL;DR version:
Can you authenticate with Facebook without having a callback URL for a web application since the web application isn't actually running on a server.
Full explanation:
I'm working on building a connectedTV platform application where the "app" itself is a bunch of HTML/JS/CSS running locally (like File -> Open on your desktop browser) and I'd like to integrate Facebook into this.
The problem is that all of Facebook's OAuth calls for the web require you to have a callback URL to redirect the user to in order to complete authentication. Here's the gotcha -- there is no URL for this application -- it's a locally running webpage on the device.
I know this is what out-of-band authentication was designed for, but I can't seem to find any documentation on how to use this (or how to do a non-callback OAuth flow) with the Facebook OAuth system.
You're describing desktop authentication or any situation where you are authenticating to FB without a server. The redirect URL you pass to the OAuth dialog is https://www.facebook.com/connect/login_success.html When the browser redirects you can get the access token. You can read all about it in the FB documentation, way at the bottom in the Desktop Apps section (https://developers.facebook.com/docs/authentication/)
Just reread your question and since the application runs inside a browser you will need to open another window to authenticate and get the access token from that.
If you're doing HTML/Javascript, use their Javascript SDK. You can log the guy in simply by using FB.login and getting the access token from the callback from that.
I really don't think this is directly possible. Unless there is something totally undocumented, Facebook has no mechanism to send authentication data except by loading a url. I'm sure it's meant at least partly as a security measure, functioning as sort of a "whitelist" of where auth data will be sent.
The only way I can think of for you to work around it might be to set up a url on a server somewhere that could answer the redirect and store the auth data, and have your client-side code poll that server to get it. Kind of a proxy authentication service, in effect. You would probably have to open a second browser window with the Facebook auth screen in it, but in theory it could work.
Related
I'm running a Classic ASP website, that has its own user authentication and login mechanism. For example, In order to remember a logged-in user, ASP creates an encrypted cookie and a 20-minute session for each connected user. If the 20 minute session is elapsed, the server revives the session from the cookie saved previously, and saves some data regarding the user to the database.
I want to to be able to allow users to connect with their Facebook or Google identity, but the mechanism used by Facebook or Google is based mainly on Javascript and on client-side code.
How Facebook or Google login can be used while maintaining server side code in ASP? (So that the ASP server can still manage the session and save data regarding it, for example whenever a session is revived)
For me somehow it seems that it may become less secure to use client-side authentication as the code may be altered easily. Isn't this the case?
If I use client-side javascript and log in with Facebook, how would I update the user data retrieved from facebook back into my database, for example the user's first and last name?
For me it sounds that it should be a "server-to-server" communication (between my ASP server and Facebook's or Google's servers) and what they propose is a "client-to-server" communication ... Any ideas how this can be done?
Any help or explanation would be very much appreciated! Thanks.
I'll try to address your Facebook-related questions one by one. However, I will not give you an implementation or any ASP-specific feedback, but only a rough approach. Additionally, I recommend that you study Facebook's documentation on Facebook Login extensively to further your understanding of the matter.
1. Facebook documents the server-side OAuth 2.0 flow in their Manually Build a Login Flow guide. Basically you redirect the user to a specific FB URL that (in the parameters) tells FB to render the "Login with Facebook" dialog, and which permission scopes to ask for. Once the user approves the Facebook Login for your webapp, they will be redirected back to your web app, e.g. with an OAuth token in the query string, that your webserver can then exchange for a user access token.
Once you obtained a user access token, you could e.g. store it in your web app user's session.
2. I don't know what you mean. Client side apps are fairly secure. Perhaps you can convince yourself about how secure JS apps are when reading about things like CORS.
3. If you only use JavaScript (e.g. Facebook's JS SDK) and you want to store e.g. app-scoped user IDs on your server, you need to expose an endpoint on your server that your JS application can submit that kind of information to.
4. You state
what they propose is a "client-to-server" communication
Who are "they", and where are the proposing this? The resources I linked to in 1. should explain how you can use Facebook login in a pure server-to-server way.
I'm trying to build a Facebook-authenticated native mobile app (Windows Phone) that connects to a web service I am creating in Node.
I'd like for a user to:
Log in to Facebook on the mobile app via a native UI or web window
If logged in successfully, create or access server-side user account data tied to that identity
Use the authenticated session to make subsequent authenticated requestsvto that user's data via the native mobile app
My question is: What's the best approach here?
Should I...
Log in the client to facebook locally in the mobile app and pass the Access Token to the node service, and then somehow map the user to my service data based on their facebook account id? That seems grossly insecure if I just pass that token in the URL.
Log the user in via a mobile browser window inside my app, and then redirect back to my Node service in the same window? How do I then make subsequent authenticated requests natively in my app?
Do something else entirely?
Sorry this is so open ended but this is the first time I have tied these things together and although there's a lot of info on each part I've yet to find something that describes the overall pattern / best practice for this design.
Your question is quite opinion based...but still I will try to help.
First of all, you can pass access token in url, its not insecure if you use https. Even if logged into facebook from your mobile app, than also its going to pass a access token in url only. If you mean having the token in http://something.com/access_token, than its not how its should be done.
If you look into the Oauth 2.0 draft you will understand that its done through setting a header Authorization with the value being the token and token_type. Take a good look at the draft.
As your solution I think its fine if you just use the first method mentioned in the question by sending the access token in header as I mentioned in your app and in turn authenticating that token from facebook on each request.
If you think this is just too long a flow for authenticating every request from facebook, than you can get access token by sending request from your mobile app to server and let the server handle the access token and store it in database which you can authenticate each request.
In any case take a look at Passport module, it has facebook and other auth built-in and should be sufficient for your needs.
Can the Stack Overflow community sanity-check this for me?
I am working on a project that involves two components: an iOS app and a mobile website. It's for a product that will interact pretty heavily with Facebook. The website is hosted on Heroku.
From iOS land, my intention is to use the Facebook iOS SDK for authentication and then hit the web API with the user's access token at https://[myappname].herokuapp.com. Since Heroku offers piggyback SSL when using the herokuapp.com domain, and the user won't be seeing this URL anyway, I figure that's fine. And this way the request is encrypted, so the access token should be safe.
From the mobile website, users will log in using Facebook, at which point my understanding is that the access token will be in their cookies, which my server can then access without having to exchange it back and forth with each request. By this reasoning it seems to me I can just stick with regular unencrypted http:// URLs for the website (and therefore use my custom domain name without having to pay a monthly fee for Heroku's SSL Endpoint add-on).
Does this all make sense? I will be the first to admit my understanding of a lot of this stuff is in serious need of an upgrade. But for now I'm just looking for someone who can tell me, "No, you're totally overlooking/misunderstanding XYZ" or "Yeah, this is how it's generally done."
Facebook advises that you should not take a dependency on their cookie format. They have stated that the cookies are "an implementation detail" that they may tweak at any time with no notice given. You should not directly access the token or other user info directly from the cookie. I personally have had some bad experiences trying to get user information directly from the cookies, mostly due to timing -- they were not always there or updated when I expected them to be.
Client-side, you should either get the access token from the Javascript SDK via FB.getLoginStatus or other method that returns the access token, and then post it up to your server. This should really be done using ssl otherwise you are susceptible to network packet sniffing where a black hat could grab the token and be able to use all of the privileges the user granted your app.
There is also a server-side option as well which hits at ssl endpoint on Facebook's servers to return an access token.
References:
"Cookies are an implementation detail": https://developers.facebook.com/blog/post/624/
Authentication docs: https://developers.facebook.com/docs/authentication/
Website login via Facebook works totally fine via HTTP.
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.
In old API the init function required path to xdreceiver and now i see it disapeared from docs.
I thought the xdreceiver is for seting cookies in your domain from facebook, but how it's working now?
Assuming your talking about an external or iframe Facebook application then Facebook uses the OAuth2.0 system and stores a cookie on your server of the form fbs_APPID where APPID is obviously the application id of your connect/canvas application.
Inside this cookie there is an access_token which is used to by both the old rest API and the new graph API to make requests on behalf of the user. This means the xdreceiver file is no longer required.
See the Facebook Developers article on authentication in OAuth2.0 here
Canvas applications can also take advantage of a new experimental signed request in order to receive the access_token.
That file is not required anymore. My understanding is that they store cookies on their side in database somewhere and then emulate cookie headers when sending HTTP requests to your app, so to your application it seems like regular cookies from a browser.
You can read briefly about cookies here, couldn't find anything better.
EDIT
Seeing BeRecursive's answer, I want to clarify that I was talking about cookies that you manually set from your canvas app. Maybe it's not what you asked about.