Facebook retrieve correct acess_tokens - php

I am having trouble finding the right access_tokens.
I have tried all ways that I have found on Google and developers.fb, but for this application(I have done it before, and made it work for another app) I just don't seem to be succesful.
I am aware that FB is constantly renewing their API's so maybe I just have found outdated solutions.
There seem to be different types of access tokens: user access tokens, and page access tokens. I find some answers in facebook documentation, but none that I understand.
The app I'm trying to create is something similar to a birthday-reminder, so it needs to be able to send offline messages(fex. be runned by a cron-job, and post to just one fb-page, owned by me, just in the name of the app itself)
I have registered the app with the page-tab on this address:
--https://www.facebook.com/dialog/pagetab?app_id=MY_APP'S_ID&display=popup&next=MY_URL--
and can now find it from the Facebook-page's settings.
Then I get to the part where i need the access token.
I dont know which of the URL's that give me what kind of access token, so I have tried both:
I have visited this URL:
(I write all links duplicate, the answer from tutorials, and my re-written link)
(of course all code pointing to my app and webpage is replaced for security reasons)
--https://www.facebook.com/dialog/oauth?client_id=0123456789011121&redirect_uri=http://www.example.com&scope=read_stream,publish_stream,offline_access--
--https://www.facebook.com/dialog/oauth?client_id=MY_APP_ID&redirect_uri=MY_REDIRECT_URL&scope=read_stream,publish_stream,offline_access--
and got:
http://www.example.com/?code=XXXXX1x1X1xxXxxX1xXxXxX1X111xX11XXXXX1XXXXXxX_XxXxxXxX1xxxXx1xXxXx-x1XxXXXxXXx1xXxXXXxXl1xX-111xXxxxXxxx1xXxxx1xXx1X1X1Xx-xxxXXXxXXXX1XXXXxx1Xxx1_xXxXxxxXx1x1XxXxxXx1XXxX-x1x1xxxXXxXxX1XX1XX1x1-xxXxxxx1Xx1XxXXXxxX#_=_
in other words(as I believe), retrieved the code:
XXXXX1x1X1xxXxxX1xXxXxX1X111xX11XXXXX1XXXXXxX_XxXxxXxX1xxxXx1xXxXx-x1XxXXXxXXx1xXxXXXxXl1xX-111xXxxxXxxx1xXxxx1xXx1X1X1Xx-xxxXXXxXXXX1XXXXxx1Xxx1_xXxXxxxXx1x1XxXxxXx1XXxX-x1x1xxxXXxXxX1XX1XX1x1-xxXxxxx1Xx1XxXXXxxX#_=_
As I have found on Google, it seems as I need to get another code as well, so then I have visited this URL(of course I have tried the first code I got first):
https://graph.facebook.com/oauth/access_token?client_id=0123456789011121&redirect_uri=http://www.example.com&client_secret=1x1111xx11111xXXx11x111111111x11&code=XXXXX1x1X1xxXxxX1xXxXxX1X111xX11XXXXX1XXXXXxX_XxXxxXxX1xxxXx1xXxXx-x1XxXXXxXXx1xXxXXXxXl1xX-111xXxxxXxxx1xXxxx1xXx1X1X1Xx-xxxXXXxXXXX1XXXXxx1Xxx1_xXxXxxxXx1x1XxXxxXx1XXxX-x1x1xxxXXxXxX1XX1XX1x1-xxXxxxx1Xx1XxXXXxxX#_=_
--https://graph.facebook.com/oauth/access_token?client_id=MY_APP_ID&redirect_uri=MY_REDIRECT_URL&client_secret=MY_APP_SECRET&code=THE_CODE_I_GOT_FROM_THE_PREVIOUS_RUN--
But when i try to run the app I get this error message:
Result: {"error":{"message":"Malformed access token XXXXX1x1X1xxXxxX1xXxXxX1X111xX11XXXXX1XXXXXxX_XxXxxXxX1xxxXx1xXxXx-x1XxXXXxXXx1xXxXXXxXl1xX-111xXxxxXxxx1xXxxx1xXx1X1X1Xx-xxxXXXxXXXX1XXXXxx1Xxx1_xXxXxxxXx1x1XxXxxXx1XXxX-x1x1xxxXXxXxX1XX1XX1x1-xxXxxxx1Xx1XxXXXxxX#_=_","type":"OAuthException","code":190}}
I have tried with different types of the ending of the access token(#=), because I dont recognize it from the other, working access token I retrieved last week, to a fully working app that I have built. That one did not have that ending, as I remember.
I also post the script here, if that is of any interest. I have found it in a tutorial, and it is quite simple code:
<?php
// CURL function to send with post method
function send_post_curl($url, $postdata = “”) {
$ch = curl_init($url);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
$data = curl_exec ($ch);
curl_close ($ch);
return $data;
}
// setup the message
$fburl = 'https://graph.facebook.com/THE_FB_PAGE_ID/feed';
$fbtoken = 'THE_ACCESS_TOKEN';
$fbmsg = 'Great API to auto status, this is the message.
Thank to WebDDR
http://webddr.net/tips-and-tricks/facebook-offline-access-step-by-step-explanation/';
$fbpcurl = 'access_token='. $fbtoken;
$fbpcurl .= '&message='. str_replace('&', 'and', urlencode($fbmsg)) ;
$result = send_post_curl($fburl, $fbpcurl);
echo 'Result: '. $result;
?>
I really hope someone can help me, I am doing this as an job I have choosen to do for my education at the university.
/Johan
PS.
Sorry, had to wrangle with the links, --link-- because the forum thought it was spam
Ds.

Try this code :
<?php
session_start();
$facebook_appid = "facebook_appid"; // Facebook appplication id
$facebook_secret = "facebook_secret"; // Facebook secret id
$redirect_uri = "https://localhost/facebook_page/events.php"; // return url to our application after facebook login ## should be SAME as in facebook application
$scope = "user_photos,email,user_birthday,user_online_presence,offline_access,manage_pages,publish_stream,user_events,friends_events"; // User permission for facebook
$code = $_REQUEST["code"]?$_REQUEST["code"]:"";
if(empty($code)) {
$_SESSION['state'] = time(); // CSRF protection
$dialog_url = "https://www.facebook.com/dialog/oauth?client_id=". $facebook_appid . "&redirect_uri=" . urlencode($redirect_uri) . "&state=". $_SESSION['state'] . "&scope=".$scope;
header("location:".$dialog_url);
}
if($_SESSION['state'] && ($_SESSION['state'] == $_REQUEST['state'])) {
$token_url = "https://graph.facebook.com/oauth/access_token?". "client_id=" . $facebook_appid . "&redirect_uri=" . urlencode($redirect_uri). "&client_secret=" . $facebook_secret . "&code=" . $code;
$response = #file_get_contents($token_url);
$params = null;
parse_str($response, $params);
echo $params['access_token'];
echo "<br>";
//$offer_url = "https://graph.facebook.com/".$dt->id."/conversations?access_token=".$dt->access_token;
//$off = #file_get_contents($offer_url);
//$dto = json_decode($off);
//echo "<pre>";
//print_r($dto);
}
?>

Related

Posting on facebook page without login from a php based website [duplicate]

I would like to post to my own Facebook page's wall from my website using PHP.
I have the following:
Facebook Application with AppID, AppSecret, ApiKey
Facebook Page with PageID
my own Facebook account - I'm the admin and the creator of the application and page mentioned above.
E.g. I write a blog post, and I'd like to get the name, the short description and a picture on my Facebook page's wall. Or I would like to publish some articles on the Facebook page every day automatically as a cron job.
Could you provide a step-by-step tutorial how to accomplish this?
I've read this article about Facebook Login:
https://developers.facebook.com/docs/facebook-login/
but I still don't know what to write in my code.
UPDATE 1
This is how I send a request for an App Access Token:
$url = 'https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id='
.Yii::app()->params['FacebookAppID']
.'&client_secret='
.Yii::app()->params['FacebookSecret'];
The response is similar to this (fake symbols):
access_token=326584076429|ax3-D39YbpDcR9rMRQn_fMvNu_s
What access_token is it? Application Access Token? How to get a User Access Token?
I tried to use the access token from here:
https://developers.facebook.com/tools/explorer?method=GET&path=me%2Faccounts
but I got the following error message:
An active access token must be used to query information about the current user
So how should I obtain the right access token?
UPDATE 2:
How can I get the right Facebook tokens in my application without any client interaction?
I'm the admin and the creator of the Facebook Application and the Facebook Page.
Step by step
Authenticate a user that is a page admin (yourself)
Request an extended access token (to get a 60 day variety as offline_access is gone). See https://developers.facebook.com/docs/offline-access-deprecation/
Call Graph API me/accounts and search thru the resulting list to find the page you're interested in
Take the page access token from the page and start using that for the calls to post
It might be possible to get an extended access token for a page access token like described in step 2, please try and let us know if that can be done for page access token too.
You can experiment with the above at https://developers.facebook.com/tools/explorer
Happy Coding!
EDIT
For getting an access token without dialogs for any user, you can use https://developers.facebook.com/tools/access_token/ to get an access token.
Steps:
Request For manage_pages permission ( Allow this process ) :
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=manage_pages&response_type=token
Get Access token from URL :
If the administrator allows this permission. You should be redirected to URL below:
http://YOUR_URL/#access_token=AAABY5jBXQz0BAEzNKkb6FZC22D7aOoKIfFuozIjoOpkGHRJ6SyzBvqx24JGooMc31374EdRFNXkOyLZCBzETRD9vhZAZC8MZD&expires_in=0
Use Access token in the URL and you should get this:
AAABY5jBXQz0BAEzNKkb6FZC22D7aOoKIfFuozIjoOpkGHRJ6SyzBvqx24JGooMc31374EdRFNXkOyLZCBzETRD9vhZAZC8MZD
Check Access token using Graph API:
https://graph.facebook.com/me/accounts?access_token=TOKEN_FROM_ABOVE
Connection will return information and access token for each page.
Implement it in your code:
You can use App access token while call a Facebook Graph API method.
Update:
If you want use API method in Facebook SDK, DEPRECATED REST API or FQL Query...
You have to use users_accesstoken this way:
Method 1:
Use your account or users to login to your Facebook page with offline_access permissions and grab access_token while login success using $facebook->getAccessToken(), and save it in database so you can use it anytime.
You can check the expiration time of the token here, token with offline_access permissions never expire except when the user changes his password or maybe anything else.
Method 2:
You can update your access_token dynamically using the code below (say goodbye to expire token). Facebook shows this solution here, it's a sample code for executing an FQL Query:
Code:
<?php
$app_id = 'YOUR_APP_ID';
$app_secret = 'YOUR_APP_SECRET';
$my_url = 'POST_AUTH_URL';
$code = $_REQUEST["code"];
//auth user
if(empty($code)) {
$dialog_url = 'https://www.facebook.com/dialog/oauth?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url) ;
echo("<script>top.location.href='" . $dialog_url . "'</script>");
}
//get user access_token
$token_url = 'https://graph.facebook.com/oauth/access_token?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url)
. '&client_secret=' . $app_secret
. '&code=' . $code;
$access_token = file_get_contents($token_url);
Try this simple function to post onto a wall:
function doWallPost($postName = '', $postMessage = '', $postLink = '', $postCaption = '', $postDescription = '') {
$FB_APP_ID = 'xxxxxxxxxxxxxxxxxxxxxxxx';
$FB_APP_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
$APP_RETURN_URL = ((substr($_SERVER['SERVER_PROTOCOL'], 0, 4) == "HTTP") ? "http://" : "https://") . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];
$code = $_REQUEST["code"];
if (empty($code)) {
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" . $FB_APP_ID . "&redirect_uri=" . $APP_RETURN_URL . "&scope=publish_stream";
header("Location:$dialog_url");
}
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=" . $FB_APP_ID . "&redirect_uri=" . urlencode($APP_RETURN_URL) . "&client_secret=" . $FB_APP_SECRET . "&code=" . $code;
$access_token = file_get_contents($token_url);
$param1 = explode("&", $access_token);
$param2 = explode("=", $param1[0]);
$FB_ACCESS_TOKEN = $param2[1];
$url = "https://graph.facebook.com/me/feed";
$attachment = array(
'access_token' => $FB_ACCESS_TOKEN,
'name' => $postName,
'link' => $postLink,
'description' => $postDescription,
'message' => $postMessage,
'caption' => $postCaption
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $attachment);
$result = curl_exec($ch);
header('Content-type:text/html');
curl_close($ch);
return $result;
}

Facebook Login Error: failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request

I'm trying to follow the example to create a server side login to Facebook from here, but with no luck. In step 7, when I try to exchange the code with a token and store it in a session for later use, I always get this error :
file_get_contents(): failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request
I know this already asked many times, but I still unable to solve this, as per this question, I tried using cURL, but it still does not work, it just returned false.
Other question told me to use the PHP SDK, but I don't know which method to use. So I'm completely lost in here.
Here's my code for calling the login form :
Login with Facebook
where LOGIN_URL is defined as :
define("LOGIN_URL", $facebook->getLoginUrl(array("redirect_uri" => APP_URL . "fb_login")));
in fb_login, I have this code :
$app->get("/fb_login", function() use($app, $facebook)
{
$code = $_REQUEST["code"];
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . APP_ID . "&redirect_uri=" . APP_URL . $_SESSION["request_uri"] // Previous URL
. "&client_secret=" . APP_SECRET . "&code=" . $code;
$response = file_get_contents($token_url); // Doesn't work
$params = null;
parse_str($response, $params);
$_SESSION["access_token"] = $params["access_token"];
// Let's try with cURL...
// $ch = curl_init();
// curl_setopt($ch, CURLOPT_URL, $token_url);
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// $output = curl_exec($ch); // Returns false
// curl_close($ch);
$graph_url = "https://graph.facebook.com/me?access_token="
. $params["access_token"];
$user = json_decode(file_get_contents($graph_url));
echo("Hello " . $user->name);
var_dump($code); die();
});
Any help is appreciated. Thanks before.
To directly answer the question, the problem is most likely that you do not urlencode (make safe for URL transport) the redirect URL. The fastest fix will be:
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . APP_ID . "&redirect_uri=" . urlencode(APP_URL . $_SESSION["request_uri"])
. "&client_secret=" . APP_SECRET . "&code=" . $code;
However, I would also suggest that you look at the Facebook SDK as this does this all for you.
Have you checked the documentation on the PHP SDK... Its quite extensive and nice.. You just need to setup your Facebook SDK as following
$facebook = new Facebook(array(
'appId' => 'your app id',
'secret'=> 'your app secret'));
Then you can retrieve login URL as
$loginURL = $facebook->loginUrl(array(
'scope' => 'read_stream',
'redirect_uri' => 'http://yourdomain/path/to/page'));
And moreover it, SDK might give you better description about your error which is handled by it which can be due to mismatch in redirect URI with app's configurations or error in app ID or secret or entirely different thing. Download SDK from here

How to post to a Facebook page with PHP

I would like to post to my own Facebook page's wall from my website using PHP.
I have the following:
Facebook Application with AppID, AppSecret, ApiKey
Facebook Page with PageID
my own Facebook account - I'm the admin and the creator of the application and page mentioned above.
E.g. I write a blog post, and I'd like to get the name, the short description and a picture on my Facebook page's wall. Or I would like to publish some articles on the Facebook page every day automatically as a cron job.
Could you provide a step-by-step tutorial how to accomplish this?
I've read this article about Facebook Login:
https://developers.facebook.com/docs/facebook-login/
but I still don't know what to write in my code.
UPDATE 1
This is how I send a request for an App Access Token:
$url = 'https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id='
.Yii::app()->params['FacebookAppID']
.'&client_secret='
.Yii::app()->params['FacebookSecret'];
The response is similar to this (fake symbols):
access_token=326584076429|ax3-D39YbpDcR9rMRQn_fMvNu_s
What access_token is it? Application Access Token? How to get a User Access Token?
I tried to use the access token from here:
https://developers.facebook.com/tools/explorer?method=GET&path=me%2Faccounts
but I got the following error message:
An active access token must be used to query information about the current user
So how should I obtain the right access token?
UPDATE 2:
How can I get the right Facebook tokens in my application without any client interaction?
I'm the admin and the creator of the Facebook Application and the Facebook Page.
Step by step
Authenticate a user that is a page admin (yourself)
Request an extended access token (to get a 60 day variety as offline_access is gone). See https://developers.facebook.com/docs/offline-access-deprecation/
Call Graph API me/accounts and search thru the resulting list to find the page you're interested in
Take the page access token from the page and start using that for the calls to post
It might be possible to get an extended access token for a page access token like described in step 2, please try and let us know if that can be done for page access token too.
You can experiment with the above at https://developers.facebook.com/tools/explorer
Happy Coding!
EDIT
For getting an access token without dialogs for any user, you can use https://developers.facebook.com/tools/access_token/ to get an access token.
Steps:
Request For manage_pages permission ( Allow this process ) :
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=manage_pages&response_type=token
Get Access token from URL :
If the administrator allows this permission. You should be redirected to URL below:
http://YOUR_URL/#access_token=AAABY5jBXQz0BAEzNKkb6FZC22D7aOoKIfFuozIjoOpkGHRJ6SyzBvqx24JGooMc31374EdRFNXkOyLZCBzETRD9vhZAZC8MZD&expires_in=0
Use Access token in the URL and you should get this:
AAABY5jBXQz0BAEzNKkb6FZC22D7aOoKIfFuozIjoOpkGHRJ6SyzBvqx24JGooMc31374EdRFNXkOyLZCBzETRD9vhZAZC8MZD
Check Access token using Graph API:
https://graph.facebook.com/me/accounts?access_token=TOKEN_FROM_ABOVE
Connection will return information and access token for each page.
Implement it in your code:
You can use App access token while call a Facebook Graph API method.
Update:
If you want use API method in Facebook SDK, DEPRECATED REST API or FQL Query...
You have to use users_accesstoken this way:
Method 1:
Use your account or users to login to your Facebook page with offline_access permissions and grab access_token while login success using $facebook->getAccessToken(), and save it in database so you can use it anytime.
You can check the expiration time of the token here, token with offline_access permissions never expire except when the user changes his password or maybe anything else.
Method 2:
You can update your access_token dynamically using the code below (say goodbye to expire token). Facebook shows this solution here, it's a sample code for executing an FQL Query:
Code:
<?php
$app_id = 'YOUR_APP_ID';
$app_secret = 'YOUR_APP_SECRET';
$my_url = 'POST_AUTH_URL';
$code = $_REQUEST["code"];
//auth user
if(empty($code)) {
$dialog_url = 'https://www.facebook.com/dialog/oauth?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url) ;
echo("<script>top.location.href='" . $dialog_url . "'</script>");
}
//get user access_token
$token_url = 'https://graph.facebook.com/oauth/access_token?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url)
. '&client_secret=' . $app_secret
. '&code=' . $code;
$access_token = file_get_contents($token_url);
Try this simple function to post onto a wall:
function doWallPost($postName = '', $postMessage = '', $postLink = '', $postCaption = '', $postDescription = '') {
$FB_APP_ID = 'xxxxxxxxxxxxxxxxxxxxxxxx';
$FB_APP_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
$APP_RETURN_URL = ((substr($_SERVER['SERVER_PROTOCOL'], 0, 4) == "HTTP") ? "http://" : "https://") . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];
$code = $_REQUEST["code"];
if (empty($code)) {
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" . $FB_APP_ID . "&redirect_uri=" . $APP_RETURN_URL . "&scope=publish_stream";
header("Location:$dialog_url");
}
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=" . $FB_APP_ID . "&redirect_uri=" . urlencode($APP_RETURN_URL) . "&client_secret=" . $FB_APP_SECRET . "&code=" . $code;
$access_token = file_get_contents($token_url);
$param1 = explode("&", $access_token);
$param2 = explode("=", $param1[0]);
$FB_ACCESS_TOKEN = $param2[1];
$url = "https://graph.facebook.com/me/feed";
$attachment = array(
'access_token' => $FB_ACCESS_TOKEN,
'name' => $postName,
'link' => $postLink,
'description' => $postDescription,
'message' => $postMessage,
'caption' => $postCaption
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $attachment);
$result = curl_exec($ch);
header('Content-type:text/html');
curl_close($ch);
return $result;
}

How to extend access token validity since offline_access deprecation

Since the offline_access Permission is deprecated in Facebook's Authentication flow, we have problem getting the so called long lived access tokens without that permission.
In Facebook's document about the deprecation it says, that server side OAuth generated access tokens will be long lived, but they are not.
Am I missing something? Some setting in app settings? Some special code I need to use to extend expiration time of access tokens? As I understand the documentation, for server side authentication, the access token which can be accessed by getAccessToken() method of PHP SDK when the user is logged in is long lived.
Edit (August 14th 2012):
A week ago the official Facebook PHP SDK was updated. The function name was changed to setExtendedAccessToken, and it was decided we actually needed to destroy the session afterwards, to remove the risk of having two active sessions.
Also, the function no longer actually returns the token, but instead stores it within the persistant data. You can therefore get the new access token with the public function getAccessToken afterwards. Grab the new SDK from official Facebook PHP SDK github page to make sure you're up to date.
Original Answer:
I have added a new public function to the base_facebook.php file, which returns an new access token which expires in 60 days. You can make a request to this function after you've received the normal access token. I've not tested, but I assume you also need to enable 'deprecate offline_access" in your Advanced settings of the Developer App.
Just add this to your base_facebook.php inside the facebook class and make a call to it. It works for me.
public function getExtendedAccessToken(){
try {
// need to circumvent json_decode by calling _oauthRequest
// directly, since response isn't JSON format.
$access_token_response =
$this->_oauthRequest(
$this->getUrl('graph', '/oauth/access_token'), array(
'client_id' => $this->getAppId(),
'client_secret' => $this->getAppSecret(),
'grant_type'=>'fb_exchange_token',
'fb_exchange_token'=>$this->getAccessToken()
)
);
} catch (FacebookApiException $e) {
// most likely that user very recently revoked authorization.
// In any event, we don't have an access token, so say so.
return false;
}
if (empty($access_token_response)) {
return false;
}
$response_params = array();
parse_str($access_token_response, $response_params);
if (!isset($response_params['access_token'])) {
return false;
}
return $response_params['access_token'];
}
Actually what was said:
If the access_token is generated from a server-side OAuth call, the resulting access_token will have the longer expiration time. If the call is made while there is still a valid access_token for that user, the returned access_token from this second call will remain the same and only the expiration time will be extended. Again, calling this multiple times during the same day will result only in the first call extending the expiration time.
Which means that it will be just longer than client-side generated token, and to receive extended token (60 days) you need do it manually by issuing request to:
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN
This token can still became invalid for several reasons, and how to handle this described in How-To: Handle expired access tokens blog post.
Update:
As of Aug 07, 2012 you can use setExtendedAccessToken method to extend access_token instead of manually constructing URL and retrieving details.
//using a javascript for popup for facebook login
FB.login(function(response) {
if (response.authResponse) {
var accessToken = response.authResponse.accessToken;
//got the accesstoken with 1-2 hours expire time
//got the accesstoken into a controller called facebook controller
$request = $this->getRequest();
$params = $request->getParams();
$token=$params['accessToken'];
//taking the access token to extend to 60days
$conf = $this->getConfigs();
$appid = $conf['fbdetails']['appid'];
$secret = $conf['fbdetails']['secret'];
$baseurl = $conf['app']['baseurl'];
//After the execution of below code , we will have a response with acess token expire time to 60days.
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=".$appid."&client_secret=".$secret."&grant_type=fb_exchange_token&fb_exchange_token=".$token;
// Above response is given for parsing.
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_URL, $token_url);
$contents = curl_exec($c);
$err = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
$paramsfb = null;
parse_str($contents, $paramsfb);
//after the parsing the contents in the above execution code the new extended accesstoken is stored.
$user_session = new Zend_Session_Namespace('fbuser');
$user_session->access_token = $paramsfb['access_token'];
//stored to session.
$this->_redirect('/home');
//Have a nice coding
An access token generated through a server-side OAuth call will be of the extended (longer) kind and you don't need to exchange it. It is already an extended token.
The only thing you must do is enable "Deprecate offline access" in your app settings. This is of course only necessary if "Deprecate offline access" was previously disabled.
Then, when you authenticate users through Facebook you will receive an access token that lives for 60 days. Authenticating multiple times during the same day will result only in the first authentication extending the expiration time.
Should you need an access token that NEVER expires for a PAGE, see my answer to a similar question here
From the developers page:
By using a long-lived user access token, querying the [User
ID]/accounts endpoint will now provide page access tokens that do not
expire for pages that a user manages.
this is for extending pages access token to expiring never, and extending the life of user access tokens expiring after 2 months(the 'new access token').
Ok so it took about a week of research but here is my solution.
in the https://developers.facebook.com/tools/explorer/ make sure that you have manage_page as part of your access_token. after that use this code with your app id, secret, and redirect:
<?php
app_id = "APP_ID";
$app_secret = "APP_SECERET";
$post_login_url = "REDIRECT_URL";
$code = $_REQUEST['code'];
//Obtain the access_token with publish_stream permission
if(empty($code)){
$dialog_url= "http://www.facebook.com/dialog/oauth?"
. "client_id=" . $app_id
. "&redirect_uri=" . urlencode( $post_login_url)
. "&COMMA_SEPARATED_LIST_OF_PERMISSION_NAMES";
echo("<script>top.location.href='" . $dialog_url
. "'</script>");
}
else {
$token_url="https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id
. "&redirect_uri=". urlencode($post_login_url)
. "&client_secret=" . $app_secret
. "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$access_token = $params['access_token'];
echo 'access token: ' . $access_token.'<br>';
if($access_token){
$token_url="https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id
. "&redirect_uri=". urlencode($post_login_url)
. "&client_secret=" . $app_secret
.'&grant_type=fb_exchange_token'
. "&fb_exchange_token=" . $access_token;
$response = file_get_contents($token_url);
$access_token = $params['access_token'];
echo 'new access token: '.$access_token;
}
}*/
?>
After that copy the 'new access token' and go back to https://developers.facebook.com/tools/explorer/ When you get there past in your new access token into the the access token field.
Then click submit. After that in the node you will see a +____ click on this and scroll down to the accounts and click that. find the page that you need the access token for and copy and paste it into the access key field. click debug and you will see that it will never expire. save that token it will stay valid as long as you do not reset your apps secret.
Inspired by previous answers, I wrote a simple token self-renewal program. First, just put your current token in the 'token.sec' file.
This program will read a token from the file, and update with a new token if everything is OK. In other programs, you just need to use the token:
$access_token = file_get_contents("token.sec");
Here we are:
<?php
$app_id = "<your app id>";
$app_secret = "<your app secret>";
$access_token = file_get_contents("token.sec");
$token_url="https://graph.facebook.com/oauth/access_token?"
. "grant_type=fb_exchange_token"
. "&client_id=" . $app_id
. "&client_secret=" . $app_secret
. "&fb_exchange_token=" . $access_token;
$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if($response === false) {
die ('Curl error: ' . curl_error($ch));
}
// Close handle
curl_close($ch);
// parse the output
parse_str($response, $params);
if(!isset($params['access_token'])) {
die("No access token");
}
echo ("New token: $access_token\n");
// eveything looks OK
rename("token.sec", "token.sec.back"); // just in case
$myfile = fopen("token.sec", "w") or die("Unable to open file!");
fwrite($myfile, $access_token);
fclose($myfile);
?>
Finally, we can add this in our crontab to renew the token once per momth:
0 0 1 * * cd /home/<path>; php exchangeToken.php

facebook is redirecting to my site outside of facebook

I'm having trouble working with my redirect uri in the authentication.
If i set it to my site, the user will authenticate, because $_Request['code'] is set, but then the user will be on my site, and I don't want that
If I redirect to apps.facebook.com/myapp, then $_Request['code'] is not set, and the user won't authenticate, but just see a blank page.
is there any way to do this in PHP, I have code running before the page is rendered.
How do you guys solve this issue?
my login function:
public static function login($redirect) {
$app_id = AppInfo::appID();
$app_secret = AppInfo::appSecret();
$home = urlencode(AppInfo::getHome());
// See https://developers.facebook.com/docs/reference/api/permissions/
// for a full list of permissions
$scope = 'user_photos,publish_stream';
session_start();
$code = $_REQUEST["code"];
// If we don't have a code returned from Facebook, the first step is to get
if (empty($code)) {
// CSRF protection - for more information, look at 'Security Considerations'
// at 'https://developers.facebook.com/docs/authentication/'
$state = md5(uniqid(rand(), TRUE));
setcookie(
AppInfo::appID() . '-fb-app',
$state,
$expires = 0,
$path = "",
$domain = "",
$secure = "",
$httponly = true);
// Now form the login URL that you will use to authorize your app
$authorize_url = "https://www.facebook.com/dialog/oauth?client_id=$app_id" .
"&redirect_uri=$home&state=" . $state . "&scope=$scope";
// Now we redirect the user to the login page
echo("<script> window.location.href='" . $authorize_url . "'</script>");
return false;
// Once we have that code, we can now request an access-token. We check to
// ensure that the state has remained the same.
} else if ($_REQUEST['state'] === $_COOKIE[AppInfo::appID() . '-fb-app']) {
$ch = curl_init("https://graph.facebook.com/oauth/access_token");
curl_setopt($ch, CURLOPT_POSTFIELDS,
"client_id=$app_id&redirect_uri=$home&client_secret=$app_secret" .
"&code=$code&scope=$scope");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
// Once we get a response, we then parse it to extract the access token
parse_str($response, $params);
$token = $params['access_token'];
return $token;
// In the event that the two states do not match, we return false to signify
// that something has gone wrong during authentication
} else {
echo("States do not match. CSRF?");
return false;
}
}
If you want to have your app on Facebook, you can just use the signed_request parameter Facebook POSTs to your canvas url. You wouldn't need to read the code once the user has approved your app. Note that Facebook always sends this parameter, even if the current user hasn't approved your app (it contains less info then).
See the documentation

Categories