Question

I'm writing a Facebook app that lists the user's friends, cross-referenced with information the user has provided about them (which is stored in a Google App Engine database). Here is how my app operates:

After the user logs into Facebook, a Graph API call is made through Facebook's Javascript SDK to obtain a list of their friends. Simultaneously, an AJAX request is sent out to my Google App Engine request handler with the user's Facebook ID, and the handler sends back a JSON object with information from the database about the user's friends. The two lists are then cross-referenced on the user's computer.

The obvious security flaw in this approach is that anyone could send a request to my handler with an arbitrary person's Facebook ID, without needing to be logged into Facebook as that person, and get all the information that person has provided about their friends. After all, Facebook IDs are publicly available.

The only way I can think of to ensure the user's identity server-side, short of implementing my own login system, is to include the user's access token in the AJAX request, since the access token is proof that the user is logged into Facebook. The request handler can then make a dummy request to the Facebook Graph API to verify that it's valid. However, this seems hacky, and I'm not sure how to deal with the possibility of the access token expiring while in transit to the App Engine server. I've also looked into the Facebook Python SDK, though I'm not sure how this might help.

How can an App Engine server verify that a Facebook user is logged into my Facebook app?

Was it helpful?

Solution

Try to use signed_request instead of sending plain facebookID's - then you can decode them on the server, using secret_id given on Facebook APP page. Then none will be able to send you "fake" queries, because they will fail to decrypt on server side.

For example, I have application which allows users vote on given entry. After user accept permissions I'm using JavaScript to send his vote to the server:

$.ajax({
            type: "POST",
            url: base_url + 'vote/send',
            data: { signed_request: response.authResponse.signedRequest, vote:vote },
});

on the server side, i'm decoding signed_request to get user FacebookID and store it as legit vote... in that way, none is able to send me fake vote, because signed_request is encrytped with in the way, which only my app is able to decode it.

response of course is the object, which comes from SDK after user aprove permission to use app.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top