Facebook Javascript API: matching a login to a user - facebook

When using the Javascript API login, it returns to the page with a number of parameters, like the access token, the user ID, and other details. If I wanted to associate a user in my database with this Facebook user, which would be the piece of data I want to store to be able to look it up later for authentication?
In other words, which token should I store, so that next time the user logs in, I can look in the database for this token and authenticate the user?
I would use the UID, but it seems easy to spoof another UID and impersonate someone else.
Thanks!

Client side spoofing is not your concern. If you are displaying FB content based upon FB authentication, then FB is responsible for the integrity of that process.
If you are using this info server side, then you need to follow the OAuth 2.0 flow which is not spoofable (to my knowledge) because you are going directly to FB for authentication.
You can't mix the two flows because you leave yourself vulnerable to attacks.
And to answer your other question, yes, you should link your DB to the UID because the access_token will change.

You can validate the fb access token with the fb js sdk. So you can take the fb-uid as save. The tokens you get from fb are only valid for a limited time, so you shouldn't save them.
UPDATE:
Regarding the saveness of the fb-uid: Your PHP script gets a signed request from facebook. That request is signed with your app's secret so that no one else can read that data. The request contains a fb-session for the current user (including the uid) and an access token.

Related

Facebook login API: avoid user hijacking

I am using FB js SDK to allow logging in on my platform. A user permits the needed access and I save his ID in my DB. The data is sent to my server via AJAX. Since the login is with FB, I can identify the user only by his ID.
Now, lets say I know someones FB ID and I know he has an account on my platform. In runtime, I can place his ID in the auth request and obtain a legit session of that user. How could that be avoided?
First of all, those are App Scoped IDs, it is very unlikely that someone would know the ID of a user who authorized your App, because it´s not the "real" ID.
That being said, you can (and should) send the User Token to the server and confirm the ID by calling the /me endpoint with that Token. You should also use appsecret_proof for API calls, more information can be found in the docs: https://developers.facebook.com/docs/graph-api/securing-requests

Facebook login to existing user database, and access tokens

Trying to add facebook login to an existing login system on a project I am working on. Built with angular, using the FB JS SDK. This is primarily to allow frictionless login, and not currently that fussed about using the access tokens to make further calls with the FB API.
So as a new user, they hit the FB login, accept permissions etc, and it fires me back an access token etc. The new user is created in my DB, along with the accesstoken, FB userid, etc.
How do I now authenticate the user with the userid and accesstoken now stored in my DB? As far as I can see, the access token changes on virtually every page load / request, so next time the user hits the FB login, or I check the FB login status the only constant thing I have is the userid.
Have done various reading on SO and FB docs eg:
https://developers.facebook.com/docs/facebook-login/web
https://developers.facebook.com/docs/facebook-login/multiple-providers
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#checktoken
How should a Facebook user access token be consumed on the server-side?
... although that has only served to confuse things further.
I imagine I would take that stored accesstoken then check its validity, however due to the various instances of access tokens expiring and being invalidated, this also seems like an incomplete solution.
So my question: How do I securely authenticate my FB users with their counterpart user in my own DB?
The Facebook login request returns user id + short lived access token (client side).
Use the server side Facebook SDK to check the validity of the access token (will return user_id and app_id fields if valid).
You can trust the user_id field returned from the Facebook API to check against your existing user database.

Can I safely authenticate a Facebook user with just Facebook Signed Request?

I want to enable my users to associate their user account with a Facebook or Twitter and allow them to login on my server with their Facebook/Twitter account instead of using the classic username/password. Basically the same idea as the login in StackOverflow.
My current approach for Facebook:
The client application will perform OAuth and then use their Facebook id to login on my server. Based on this Facebook id, the server will lookup the associated user account and perform login without asking for username/pasword. However just relying on the Facebook id to login is not very safe, as that is the same as using only a username to login instead of username & password.
So to make sure the Facebook id is authentic, the client application will also provide a FBSR (Facebook Signed Request, see: https://developers.facebook.com/docs/facebook-login/using-login-with-games/#checklogin) with the login request.
The server will check two things with this FBSR:
The Facebook id in the request must be the same as the one hidden in the FBSR
Server will recalculate the signature part via the Facebook secret key. This must match with the signature in the FBSR .
Normally the server should perform a check with the Facebook server with the oauth_token to be 100% sure of the users identity. However I need skip this in order to avoid dependency to Facebook server on our server.
I have 2 questions:
1) Is this above approach good enough? Can it be improved (without server-to-server communication)?
2) I want to do the same with a Twitter account, but the their signed request is different then Facebook. It seems the Twitter user id is embedded in the oauth_token, so my approach may work with a little tweak, but I am not sure whether the user id is always part of the oauth_token and cannot get this confirmed after searching the internet.
I think that your approach is good enough and don't see any way to avoid server-to-server communication with a signed request. Bear in mind that, with Facebook Graph Api Version 2, in order to protect the privacy of the user, Facebook will send out not the real user id, but one generated for apps. It will also be possible to enable anonymous login.
I am not sure of what you're trying to do with Twitter, and why you compare the APIs (they're quite different). The Twitter login, also know as Sign in with Twitter, used for any website or mobile app, should work for you too.

NodeJS Confirm Facebook Credentials

In this scenario I have an app in which:
The user is to log in using Facebook Single Sign On (SSO) on a mobile device (iOS in this case).
The returned Facebook credentials are then sent to a NodeJS server (using the same Facebook App Key) and need to be validated as truly being that users Facebook credentials before they are associated to a program based account.
The Problem:
Given access to everything returned by Facebook as the result of authentication, how can this data be used to confirm that authorization with Facebook?
There are two things you can do:
Facebook will generally pass you a signed request which you can check with a basic SHA2 hash. If the hash is correct, you can assume the user was really authenticated using facebook.
Facebook will generally also pass you a (short lived) access token which you can exchange for a longer lived access token using the graph api. Upon this exchange completing you are as sure you can be that the user is who he says he is.
https://graph.facebook.com/me?access_token=TOKENGOESHERE
If a user is returned, and their ID is what the client claims, they are most likely who they say they are.

Is using the Facebook access token a secure way to validate a user?

On my app the user can sign to Facebook and the app then has the user's access token (say it's 'abc'), I want to use this token to create a user on my own server.
Is it safe to send this access token to my server (using SSL), then get the user's username and ID using https://graph.facebook.com/me?access_token=abc on my server and check that the application the token belongs to is mine with https://graph.facebook.com/app?access_token=abc. If it is my application I then store the user in my user's database and/or log them in.
Can this system be fooled? Can you think of a way someone could log in as someone else?
You should check out all of the Authentication documentation and the Oauth spec to see the different auth flows available
Broadly speaking, you can create a user on your server based on the access token, and be reasonably certain that when you get an access token from Facebook for the same user ID that it's the same person.
If you require very high security for the app you can take steps to ensure the user's access token wasn't produced via malware or the Facebook user being tricked, there's an example showing protection against CSRF in the Server Side Authentication documentation, and there's also a reauthentication flow you can use
I assume that you are using facebook sdk for this, if so the facebook sdk takes care of the security for you and you don't have to worry about a thing.Supposing that you are accessing the api without the sdk then there are two things that must be noted:
1) Auth token expires frequently(facebook has taken great pains to ensure that the user is protected)
2)Making a request with just auth token is not enough there are some other parameters that are needed that can't be faked especially if you are doing this server side since an extra layer is added that fb calls server flow authentication
3)On top of that there are a lot of permissions that are in place that the user has to give in order for an application to access some data.The link below provides a nice article on authentication you can take a look
https://developers.facebook.com/docs/authentication/
So long story short it is safe.