REST API for website which uses Facebook for authentication
UPDATE: see below
I've been thinking hard about this question too. It's not entirely clear to me yet but here's the route I am thinking of going. I am creating a REST API an my users only auth with Facebook connect.
On the CLIENT:
- Use the Facebook API to login and get an OAUTH2 code.
- Exchange this code for an access token.
- In every call to my custom API I'll include the Facebook user id and the access token.
On the API (for every method that requires user authentication):
- Make a request to the /me Facebook graph using the access token from above.
- Verify that the Facebook user id returned matches the user id passed to my API from above.
- If the access token has expired additional communication is required.
I have yet to test this. How does it sound?
--- Update: July 27th, 2014 to answer question ---
I only use the above exchange once upon login. Once I determine which user is logging in, I create my own access token, and that token is used from that point going forward. So the new flow looks like this...
On the CLIENT:
- Use the Facebook API to login and get an OAUTH2 code.
- Exchange this code for an access token.
- Request an access token from my API, including the Facebook token as a parameter
On the API
- Receive access token request.
- Make a request to the /me Facebook graph using the facebook access token
- Verify that the Facebook user exists and match to a user in my database
- Create my own access token, save it and return it to the client to be used from this point forward
This is my implementation using JWTs (JSON Web Tokens), basically similar to Chris' updated answer. I have used Facebook JS SDK and JWT.
Here's my implementation.
Client: Use Facebook JS SDK to log in and get the access token.
Client: Request JWT from my API by calling
/verify-access-token
endpoint.MyAPI: Receives access token, verify it by calling
/me
endpoint of Facebook API.MyAPI: If access token is valid, finds the user from database, logs in the user if exist. Create a JWT with required fields as payload, set an expiry, sign with the secret key and send back to the client.
Client: Stores the JWT in local storage.
Client: Sends the token (the JWT from step 5) along with the request for the next API call.
MyAPI: validate the token with the secret key, if token is valid, exchange the token for a new one, send it back to the client along with the API response. (No external API calls for verification of the token here after) [if the token is invalid/expired request client to authenticate again and repeat from 1]
Client Replaces the stored token with the new one and use it for the next API call. Once the token expiry is met, the token expires revoking access to API.
Every token is used once.
Read more answers about security and JWT
How secure is JWT
If you can decode JWT how are they secure?
JSON Web Tokens (JWT) as user identification and authentication tokens