Check If access_token is valid - facebook

I have A Facebook App which auto post birthday reminders.
I stored tokens in database.
But Now most of them are expired.
I am trying to make a PHP file which will find valid tokens from my database and save them.
$query = mysql_query("select fb_token from fb_user")
while ($row = mysql_fetch_array($query)) {
$url = "https://graph.facebook.com/me?access_token=".$row['fb_token']."";
}
By with this Code I'm getting each token. Need Help to Save only valid tokens.

You can create request to the following Open Graph URL, basically you need to provide your APPID and access_token.
https://graph.facebook.com/oauth/access_token_info?client_id=APPID&access_token=xxxxxxxxx
The response will contain expiry time of specified token.

Related

How to extend facebook access token in python

I am using the Python facebook-sdk client library.
I currently have a short-lived access token obtained from https://developers.facebook.com/tools/accesstoken/ that I copy the code from the site into my code for authentication.
graph = facebook.GraphAPI(access_token)
This token however expires after 60-mins. I am looking to extend this to a 60 day-long lived token so that don't need to manually copy in new every time it expires. I can find numerous answers on how to do this in different formats, however not python (or at least not simply without log in page etc.).
[for reference, the code I will be using is only intended for my use, and as such, I am not looking to create a log in page. I just want to be able to extend the token I already have].
Not sure if this was available in python's FB API when the question was originally asked, but a neater approach to extend the expiry of the access token would be:
graph = facebook.GraphAPI(user_short_lived_token_from_client)
app_id = 'app_id' # Obtained from https://developers.facebook.com/
app_secret = 'app_secret' # Obtained from https://developers.facebook.com/
# Extend the expiration time of a valid OAuth access token.
extended_token = graph.extend_access_token(app_id, app_secret)
print extended_token #verify that it expires in 60 days
here's an edited version , compatible with latest api versions:
import requests
import json
access_token = 'your token' # Obtained from https://developers.facebook.com/tools/accesstoken/
app_id = "your app id" # Obtained from https://developers.facebook.com/
client_secret = "app secret" # Obtained from https://developers.facebook.com/
link = "https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=" + app_id +"&client_secret=" + client_secret + "&fb_exchange_token=" + access_token
s = requests.Session()
token = s.get(link).content
token=json.loads(token)
token=token.get('access_token')
print token
According to their subsection on extending short lived client tokens, you'll need to take in your short lived client token and, having filled in the relevant app data, send a GET request from your server to the following endpoint:
GET /oauth/access_token?
grant_type=fb_exchange_token&
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={short-lived-token}
The response will contain your long-lived access token which can then be passed back to the client or used on your server. If you don't currently have a module for performing HTTP operations, I highly recommend Requests.

How to verify user login when using Facebook Javascript SDK

I've already gone through this question, but my question is different. I am unsure of how can javascript login be sure and how can some-else not login into others account.
According to the getting started FB.authResponse is called when the login is successful, but in the client's side of course.
Then we can get the userId & accessToken out of the response, we can also make call to /me to get more information. In order to put that user into session, all this info about successfull javascript login has to be sent to the server and this is where I get confused.
After all it's HTTP, every other request is different and can be replicated.
May be it's just that I'm confused, about how someone can't hack and immitate any other users' facebook id to login into his account.
For e.g. after the authentication is success, I make an ajax call to my server providing
the fb-user-id and then I match it with the database and put the appropriate user in the session, but not since this is fb-user-id is not verified again in the back-end (or is it verified?, I didn't found anything though about it) that this particular user is the one who actually signed up in my application, then a same login request with someone else's fb-user-id can be made to login into his account.
I'm sure, I'm not the first one to have this confusion. Please help to clear this confusion, as I've read the docs many times now, but still unable to figure out why can't someone else login into someone else's account.
EDIT
I found this similar question but the guy here doesn't answer how he verified backend login or may be I was unable to understand.
According to :
How to securely authorize a user via Facebook's Javascript SDK
Send the signed_request field to your server, which is being received in the authResponse using the javascript sdk
Then in the server-side, the following procedure as stated in the documentation has to be followed for verfication :
Once you have captured the signed request, you need to perform three steps:
Split the signed request into two parts delineated by a '.' character (eg. 238fsdfsd.oijdoifjsidf899)
Decode the first part - the encoded signature - from base64url
Decode the second part - the 'payload' - from base64url and then decode the resultant JSON object
Here is an example in PHP:
function parse_signed_request($signed_request) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$secret = "appsecret"; // Use your app secret here
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
// confirm the signature
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
This will produce a JSON object that looks something like this:
{
"oauth_token": "{user-access-token}",
"algorithm": "HMAC-SHA256",
"expires": 1291840400,
"issued_at": 1291836800,
"user_id": "218471"
}
After getting the user_id, that particular user can be put in session, although there needs to be other checks for proper authorization.
As a second check, the issued_at can be checked to see if it's not more than 10 mins old.
Taken from here.
However, there may be scenarios where your app_secret may be
compromised. To take care of this case, you should follow step #3, as
the exchange of code for access_token can happen only once and within
10 mins of it's issue. If the user doesn't have an account with your
site, then you anyway need step #3 to use the access_token for
retrieving other necessary user data, like name, email, etc from FB.
In order to refresh token the following call can be made from your server
GET /oauth/access_token?
grant_type=fb_exchange_token&
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={short-lived-token}
Reference
When making a graph API call you need an access_token that is unique to an user and an app.
When query a call concerning a user-id and just manipulate it, the access-token you are using belongs to the original user and Facebook API just returns the information the manipulated id may get. This may be different if the manipulated user is a friend of the original or not.
Simplified:
Your user logs in at your website and accepts your scope params.
Now Facebook returns a user-id and an user access_token that is valid just to this user and your one app.
Most graph calls now needs a user-id and an access_token. If you do an update request for example on the users friend lists and the access_token does belong to the user, graph api will return an error.
It you store the access_token on your server and send it to your server via HTTP-Request / AJAX and not via https, a man in the middle could catch the access-token and abuse it.

Send FB user a notification via App

I'm getting an App access token via the Facebook API.
$app_id = "ID";
$app_secret = "SECRET";
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".$app_id."&client_secret=".$app_secret."&grant_type=client_credentials";
$app_token = file_get_contents($token_url);
When $app_token is echoed, the following is displayed
access_token=xxxxxxxxxxxxxxxxxxxxxxxx // access token x'ed out for security.
The "ID" is equal to my application ID (which I'm not silly enough to write). There's a vertical bar that separates the ID from another alphanumeric string.
I'm not very experienced with this aspect of the API, particularly doing what involves App access token rather than user access tokens.
So, when I tried to send a test notification in a php script
$url = "https://graph.facebook.com/".$fb_user_id."/notifications?href=".$url."&".$app_token;
$result = file_get_contents($url);
$result gives me an error message as such:
{"error":{"message":"A user access token is required to request this resource.","type":"OAuthException","code":102}}
As indicated on https://developers.facebook.com/docs/concepts/notifications/, you should using HTTP POST requests to send notification to the user of your apps, not HTTP GET requests.

How to get value of "expires" parameter of access_token using Facebook PHP SDK?

My Facebook PHP SDK application logged in to Facebook and received access_token.
How to get the value of "expires" parameter later time using PHP SDK?
Facebook API provides the expires parameter along with the access_token in its response as stated here: https://developers.facebook.com/docs/authentication/
In addition to the access token (the access_token parameter), the response contains the number of seconds until the token expires (the expires parameter). Once the token expires, you will need to re-run the steps above to generate a new code and access_token, although if the user has already authorized your app, they will not be prompted to do so again. If your app needs an access token with an infinite expiry time (perhaps to take actions on the user's behalf after they are not using your app), you can request the offline_access permission.
If you're trying to get the time remaining for an access token, I don't believe Facebook even has a method via the API for you to do this. It's easier to just request a new access token, or to request an "offline_access" token which is also documented in the above reference.
To retrieve the "expires" parameter with the Facebook PHP SDK, you need to add a few lines to the base_facebook.php script provided inside the SDK:
//base_facebook.php
//At Line 728
if (!isset($response_params['access_token'])) {
return false;
}
//Add these two lines here
$_SESSION['token_created_time'] = time();
$_SESSION['token_expires'] = $response_params['expires'];
return $response_params['access_token'];
Once your are connected with your application, you can access your "expires" parameter and the remaining time before your token expires with the following :
//Your "expires" parameter :
echo $_SESSION['token_expires'];
//The remaining time before your token expires :
echo $_SESSION['token_expires'] + $_SESSION['token_created_time'] - time();
I hope it would help.

Having Trouble Accessing Email from Facebook Oauth

I can't get the proper token to reach the extended user information (specifically email) from the Facebook API. I've correctly given my app permission to retrieve the email, so I know I have the correct permissions. I'm trying to convert a session to a token using the exchange_session method as you can see below in my code:
$url = 'https://graph.facebook.com/oauth/exchange_sessions';
$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,$url);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS,'type=client_cred&client_id=' . FB_APPID . '&client_secret=' . FB_SECRET . '&sessions=' . $session->session_key);
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
$buffer = curl_exec($curl_handle);
curl_close($curl_handle);
$tokendata = json_decode($buffer);
$user = json_decode(file_get_contents('https://graph.facebook.com/me/?wrap_access_token=' . $tokendata[0]->access_token));
print_r($user);
If I use the '/me' it always errors out with
"An active access token must be used to query information about the current user."
If I swap out '/me' with the current user ID, it will give me the basic user info, but not the extended info.
The token that I get back is indeed the full token with session info in this format:
123456789012345|6.abcdefghijklmnopqrstuv__.1234.1234567890-1234567890|abcdefghijklmnopqrstuvwxyza.
Help?
Thanks!
Andy
Should it be /me/?access_token= instead of /me/?wrap_access_token=?
Use official facebook's php sdk to avoid the headache with tokens handling