Facebook access token and AJAX calls
I have an app that I originally coded as server-side authentication in PHP.
However, I want the client to do AJAX calls into my server, and then based on the Facebook userId do some queries in my database. I can't just accept a userId variable, because anyone can just spoof it, so I think I need to access the user's accessToken.
However, this being an AJAX call into a PHP file on the server, I don't have the ability to use the same server-side authentication methods as presented in the examples.
So I think the client needs to pass an FB access token through the AJAX call, and then I validate that access token server-side, and then use it to get the user's id and additional information.
However, if I use server-side authentication, the client never actually retrieves its access token from Facebook, only the server has it, which means the client can't pass the access token.
My question is: once I do the original server-side validation, should I store the access token server-side based on the cookie and then get the access_token that way?
Or, is there a better practice for Facebook apps so that I don't need to worry about leaking an access token via cookie spoofing?
First of all, you should not store the access token in a cookie or send it through a ajax call. The access token is a sensible data that must be always invisible.
I don't know if it is the best way to do this, but I always use the signedRequest. This is a secure data to send to your server, because it is encrypted with your app secret, which nobody knows...
If you pass the signedRequest (from FB JS SDK) to your server, you can retrieve a valid access token. In PHP, it looks like this, assuming you are passing the signedRequest by POST:
$signed_request = $_POST['signedRequest'];
$data = parseSignedRequest($signed_request);
$token_url= 'https://graph.facebook.com/oauth/access_token?' .
'client_id=' . YOUR_APP_ID .
'&redirect_uri=' . // when using the JS signedRequest, leave this blank
'&client_secret=' . YOUR_APP_SECRET .
'&code=' . $data["code"];
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$access_token = $params['access_token']; // here is your access token
You will need these functions:
function parseSignedRequest($signed_request) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64UrlDecode($encoded_sig);
$data = json_decode(base64UrlDecode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
return 'Unknown algorithm. Expected HMAC-SHA256';
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, YOUR_APP_SECRET, $raw = true);
if ($sig !== $expected_sig) {
return 'Bad Signed JSON signature!';
}
return $data;
}
function base64UrlDecode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
Of course, if you store the access token in your DB, you'll not need to pass through this, but be careful with the token expiration.
If the user already authorized your app and is logged in Facevook, you can retrieve the signedRequest from the cookie $_COOKIE[('fbsr_' . YOUR_APP_ID)]
, but I don't trust very much on this data...
上一篇: iOS版Facebook SDK 3>获取已签名的请求
下一篇: Facebook访问令牌和AJAX调用