14
votes

I need to verify that users on my iPhone app are actually logged in to my Facebook app. I'm able to verify their user id by retrieving it with their Access token:

https://graph.facebook.com/me?fields=id&access_token=XXXXXXXXXXXXXXX

The security issue I foresee is that, they can send me any valid access token, and it will return their user id. I need to also validate this token is for my specific app. Is there a way to return the Application ID in this request to validate that?

4
I am confused. Why are you taking an external token? And more importantly, how are you asking the users to give it to you? Passing token around is a security issue - if someone gets their hand on it, they can impersonate the user and your application. You should be using the FB iOS SDK to ask the user to login to Facebook from inside your app instead.Franci Penov
I am. They log into my facebook app on my iphone app. The problem is that some actions must be completed/verified on the server through my API. Since facebook is the authentication/identity management system for my app, when they make certain API calls to my server, I need to verify that the user is who they say they are. They pass their user id and access token and I verify it on the server.Eric Di Bari
I see. It's an interesting scenario. Would you mind sending me a short email to francip at fb.com about this? I want to make sure the SDK folks are thinking about identity transfer between client and server apps.Franci Penov

4 Answers

21
votes

Facebook now provides support for debugging an Access Token. You can retrieve the information related to a particular Access Token by issuing a GET request to the debug_token connection. Something like:

GET /debug_token?
     input_token={input-token}&
     access_token={access-token}

Where, input-token: the access token you want to get information about and access-token: your app access token or a valid user access token from a developer of the app

And this will return the following information:

{
        "data": {
            "app_id": 000000000000000, 
            "application": "Social Cafe", 
            "expires_at": 1352419328, 
            "is_valid": true, 
            "issued_at": 1347235328, 
            "scopes": [
                "email", 
                "publish_actions"
            ], 
            "user_id": 1207059
        }
    }

You can get more information about it in the Getting Info about Tokens and Debugging reference.

14
votes

Yes. You can query this:

https://graph.facebook.com/app?access_token=TOKEN

It will return the name, id and several stats about the app that created the access token.

1
votes

Here is my implementation in Python 3, implementing a single Facebook Batch Request. This should get you both the APP and USER data that is tied to the user's access_token, in one call.

#Build the batch, and urlencode it
batchRequest = '[{"method":"GET","relative_url":"me"}, {"method":"GET","relative_url":"app"}]'
batchRequestEncoded = urllib.parse.quote_plus(batchRequest)

#Prepare the batch and access_token params
dataParams = 'access_token=%s&batch=%s' % (fb_access_token, batchRequestEncoded)
dataParamsEncoded = dataParams.encode()
fbURL = 'https://graph.facebook.com/'

#This will POST the request
response = urllib.request.urlopen(fbURL, dataParamsEncoded)

#Get the results
data = response.read()
data = json.loads(data.decode("utf-8"))

There is probably a more pythonic way to implement some of the encoding calls I wrote, but I just wanted to show what exactly worked for me.

0
votes

You can use appsecret_proof on your api calls.

From the official documentation:

Access tokens are portable. It's possible to take an access token generated on a client by Facebook's SDK, send it to a server and then make calls from that server on behalf of the client.

You can prevent this by adding the appsecret_proof parameter to every API call from a server and enabling the setting to require proof on all calls. This prevents bad guys from making API calls with your access tokens from their servers.

Example:

https://graph.facebook.com/app?access_token=TOKEN&appsecret_proof=<app secret proof>

In PHP:

$endpoint = sprintf(
    'https://graph.facebook.com/app?access_token=%s&appsecret_proof=%s',
    urlencode($accessToken),
    urlencode(
        hash_hmac('sha256', $accessToken, $appSecret)
    )
);

You can now trust that the response that you got can be used for authentication.