Facebook API: /oauth/access_token not working - php

I am trying to obtain a user access token from Facebook with the PHP-SDK. The server-side log-in process works great, redirecting to the correct page and providing $code too.
After the redirect (and checking whether $code exists) I then call the following API method to exchange $code for a user token (API parameters are suppressed here):
$fb->api('/oauth/access_token',array(
'client_id' => APP_ID,
'client_secret' => APP_SECRET,
'redirect_uri' => REDIRECT_URI,
'code' => $code
));
$fb_token = $fb->getAccessToken();
echo $fb_token;
Unfortunately, all I get from this script is still the app token. In fact, reducing the script to just the following does not make any difference:
$fb_token_user = $fb->getAccessToken();
echo $fb_token_user;
So I assume it is all about the /oauth/access_token call which for some reason is not working or at least does no action. It does not return any errors either.
I have tried and tested several alternatives, such as the get_file_contents() method suggested in the Facebook tutorial as well as adding additional parameters to the above API call (e.g. type=client_cred and more), but never succeeding.
Does anybody see why the API call is not working? Is it the script or could it be some app setting on Facebook?
Thanks in advance!

Solved! The code in the question is still not working in spite of ever so many threads on this and other communities stating it does (oddly enough it seemed to work for them).
So I figured I had to go back to the file_get_contents() method as explained by Facebook and it turns out this method was previously not working because allow_url_fopen is disabled on my server. Not wanting to undergo the risk of enabling it, I discovered cURL as a work-around.
And here is the working code:
// cURL Load Function
function cURLget ($ch_url) {
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$ch_url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
$ch_send = curl_exec($ch);
curl_close($ch);
return $ch_send;
};
// Obtain User Token
$fb_token_get = cURLget("https://graph.facebook.com/oauth/access_token"
. "?client_id=" . APP_ID
. "&client_secret=". APP_SECRET
. "&redirect_uri=" . urlencode(REDIRECT_URI)
. "&code=" . $CODE
);
$fb_token_params = null;
parse_str($fb_token_get,$fb_token_params);
// Print Token Data
echo "Token: " . $fb_token_params['access_token']
. "<br />Expires: " . $fb_token_params['expires'];
Thanks to #FabioAntunes for trying to help me with the original code and to #ShawnECarter for his script for the cURL Load Function.

Stumbled upon this problem today too. Seems my PHP SDK (v.3.2.2) offers a function that solves the problem: setExtendedAccessToken(). (Does pretty much the same thing: Calls graph's "/oauth/access_token" and exchanges the old token against a "long-lived" one).

Related

400 error code when using Google oAuth2 server-side authentication

In my PHP-based application, I've been using the Google oAuth 2 server-side flow for several years, and it has always worked flawlessly, until recently. I've been reading on any possible breaking API changes, but can't find any. Most questions having similar issues are several years old, so I'm asking a new question. It is particularly strange that this stopped working without any change on my end.
Below details are from my dev environment, but I'm getting similar results on production. This is the URL I use for getting the permission (not sure what the correct terminology is):
https://accounts.google.com/o/oauth2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state=%2Fprofile
&redirect_uri=http%3A%2F%2Fwww.jungledragon.org%2Fapps%2Fjd4%2Fsignin%2Fgoogle%2Fcallback
&response_type=code
&client_id=652476484487.apps.googleusercontent.com
&approval_prompt=auto
This seems to work correctly. If not given already, the user indeed sees the Google screen to grant access. If the user then approves proceeds, they are redirected back to my application given the callback URL.
With permission given, the next goal is to get some user data. For this, the following code is used:
// get values from the callback URL
parse_str($_SERVER['QUERY_STRING'],$_GET);
$code = $_GET['code'];
$error = $_GET['error'];
$state = $_GET['state'];
// an error reason is returned, something went wrong
if ($error_reason) { return false; }
// our app is recognized, get access token by doing a post to the Google oAuth service
$url = 'https://accounts.google.com//o/oauth2/token';
$data =
"code=" . urlencode($code) .
"&client_id=" . $this->CI->config->item('pd_oauth_google_clientid') .
"&client_secret=" . $this->CI->config->item('pd_oauth_google_clientsecret') .
"&redirect_uri=" . urlencode($this->CI->config->item('pd_oauth_google_callbackurl')) .
"&grant_type=authorization_code";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
// check the result. anything but a 200 return code is an error
$info = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if ($info!=200) { return false; }
As you can see, a CURL POST request is created with several parameters. None of the param values have changed and this has worked for years, yet now stopped working, for unknown reasons.
The particular problem is that the response of the post is the Google Error 404 (Not Found)!! page. This doesn't give me any meaningful info on what could be wrong.
Help is greatly appreciated, as this issue blocks all users on my production site that log in via Google authentication.
https://accounts.google.com//o/oauth2/token
will result in a 404
https://accounts.google.com/o/oauth2/token
will result in
{
"error" : "invalid_request"
}
No idea why your code worked for the last year you have an extra / in there

How to use facebook access_token

I´m building a facebook app with php,
everything works perfect, I do successful dialog auth
I have the short_live token
I generate the long_live_token and save it to some directory
what I want to do is that in canvas app the user selects some stuff and activates a mechanism that regularly posts stuff, this is why I save the token.
but what can I do with it?!
I find a lot about generating the access_token but nothing about how to use it!?
Where can I add it as parameter? What is the key?
example:
I´m using facebook sdk for php for post sth. to a wall like
$msg_body = array(
'message' => "wassup yo"
);
$facebook->api($uri, 'post', $msg_body );
but this only works if
$facebook->getUser();
is returning a user
how can I use my stored access_token to do the same?
I believe there is a function called "setAccessToken" in the Facebook PHP SDK. You would just need to set it with that function and it gets added to every call automatically.
Manual way:
$params = array(
'message' => 'wassup yo',
'access_token' => '[your-token]'
);
$facebook->api($uri, 'post', $params);
You could also do this with CURL, this would be an example URL;
$url = 'https://graph.facebook.com/' . $userId .
'/feed' .
'&access_token=' . $accessToken .
'&message=' . $userMessage;
Basically you just add the Access Token as a parameter like the message.
Just make sure you are using secure calls, see this article for an example of using CURL with the Facebook API and usage of "appsecrect_proof": http://www.devils-heaven.com/extended-page-access-tokens-curl/
IMPORTANT: Be sure that the message parameter is always 100% user generated without any prefilling (see Platform Policy) and keep in mind that you need to go through a review process with pulish_actions to make it available for other Users: https://developers.facebook.com/docs/apps/changelog

Understanding how to publish to a facebook page as a page via a website (app)

I have spent quite some time now trying to establish how, and then the best practise to push some data from my web server to the facebook page created for this purpose.
I have read and understand the process of using access tokens. I have generated an access token for myself, which can be used to post to the page as me ok. I understand this should be used to generate the access token for the page to post as the page which is a ittle more tricky. However, this process involves me logging in and generating an access token which seem inherently bad / inconvenient for an automated process.
For this reason i followed the guides to create an app. I (think I have) linked the app to the page, and thus attempt to push data via the appid and secret from my php code to the page.
When doing this I am presented with this error
{"error":{"message":"(#210) Subject must be a page.","type":"OAuthException","code":210}}
my testing code is this:
$data['picture'] = "http://www.example.com/image.jpg";
$data['link'] = "http://www.example.com/";
$data['message'] = "Your message";
$data['caption'] = "Caption";
$data['description'] = "Description";
$data['access_token'] = $app_token2;
$post_url = 'https://graph.facebook.com/'.$app_id.'/feed';
$url1 = "https://graph.facebook.com/endpoint?key=value&access_token=".$app_id."|". $app_secret ;
echo "<br>$post_url";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $post_url);
//curl_setopt($ch, CURLOPT_URL, $url1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($ch);
curl_close($ch);
echo "$return";
I appreciate using the app for server initiated posting using a permanent (ish) secret is the correct way, but I have found very little documentation on how this process is achieved, hence this question.
Your $post_url is pointing to your $app_id variable, the message says it should point to a page, try getting the id of your page from the /me/accounts endpoint of the graph and putting that in there instead. Though I suspect you will need to use a page access_token (also from the /me/accounts endpoint ) to post to your page
Right, I have worked on this for quite some time and found several errors in my code, but have not answered the question fully.
For starters, you do not post to the appid as mentioned above - its just wrong. The code for posting to userid/feed works when using an access token generated from appid + secret using
$url2 = "https://graph.facebook.com/oauth/access_token?client_id=".$app_id."&client_secret=". $app_secret."&grant_type=client_credentials";
this app access token is valid for as long as your app secret is. Also, if I generate a temporary access code for ME via the graph explorer, parse me/accounts manually and use the page token in
$post_url = 'https://graph.facebook.com/'.$page_id.'/feed';
It posts correctlly as the page.
Secondly, all server side call are required to have appsecret_spoof in them which is generated from
$appsecret_proof= hash_hmac('sha256', $app_token2, $app_secret);
now, according to the facebook docs, a http get call to my userid/accounts should yield page access tokens for all pages the user administers (and also presumably the app).
This can also be called directly by using
$url3 = "https://graph.facebook.com/".$page_id."?fields=access_token";
so when a get is made to this address (including app access token & appsecret_spoof) all i get is 'True' ??
Likewise, when the correct call to
$rob1 = "https://graph.facebook.com/".$user_id."/accounts";
I receive an error
{"error":{"message":"(#10) Application does not have permission for this action","type":"OAuthException","code":10}}
OK permission issue then ! Well the documentation says that only manage_pages is required to retrieve the page token from page_id/accounts, so I trawl through lots of pages and find you can do this by calling this url
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=read_stream
This throws up via facebook gui an accept / deny page for each scope (i ended up adding manage_pages, publish_stream & read_stream to my app) none of which seem to solve the problem !
Right sorted !! FWIW the code above functions correctly, however the way it is setup on facebook leaves a lot to be desired !!!
I began messing with my app and changed its name, type (was an app linked to the page - now isnt) removed perms and also changed the domain name (removed) and all site url details (also removed). this prompted a different error msg which stated the domains did not match. So, I readded just the app domain & site url, saved and all of a sudden my failed code started working !
Having tidied my code up a little I can now see the page access token just fine as I expected. I just wish the facebook guides would cross reference this setup as it is not at all obvious !!!
my working code ended up as thus ($perm_url is used as one time link to allow perms via gui)
$perm_url = "https://www.facebook.com/dialog/oauth?client_id=".$appid."&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope=publish_stream,manage_pages,read_stream,status_update";
echo "<br>Test";
$facebook = new Facebook(array('appId' => $appid , 'secret' => $appsecret ,));
$access_token = $facebook->getAccessToken();
$pageinfo = $facebook->api("/".$page_id."?fields=access_token");
$page_access_token = $pageinfo['access_token'];
echo "<br>Holy Grail = $page_access_token ";

Can I use open graph simply to obtain public facebook information?

I am trying to use open graph to read story information off a public facebook page (http://www.facebook.com/onlinehorsesupplies). I want to obtain the message content of the latest post for use elsewhere on the related ecommerce website. I could scrape it but using open graph seems like it should be a better way to go.
Using the http://developers.facebook.com/tools/explorer I found the URL I need to use quite easily but I had to click on the 'get access token' to make it work. I use this URL:
https://graph.facebook.com/188288097875046?fields=posts&access_token=
If I use the access token copied off the explorer page it works fine. If I use an access token off my own app it fails with "Bad request...". How can I get an appropriate access token in my php code?
I think your app needs to request a token first. At least thats how it worked for me.
Something like:
$app_token_url = "https://graph.facebook.com/oauth/access_token?" . "client_id=" . $app_id . "&client_secret=" . $app_secret .
"&grant_type=client_credentials";
$response = file_get_contents( $app_token_url );
parse_str( $response, $fbinfo );
then you can use that token for the request...

Automated Comment Cron Job No Longer Working: Fatal error: Uncaught OAuthException: Bad signature

A few months ago, I wrote a small app that would parse a string from my client's blog page and post it as a comment to their Facebook wall, which I have the credentials to manage.
The client only had to authenticate my app ONCE, and then, via the now-depricated "offline_access" permission, I could post on their behalf to their wall.
The code no longer works despite whether I use the old SDK or the latest SDK. I have attempted to migrate my code (below) to the latest version of the SDK and latest protocols for handling authentication to no avail. I have also had the client re-authenticate my app with the "manage_pages" scope (which I've had in place since day 1) with no difference.
The error I get is Fatal error: Uncaught OAuthException: Bad signature
I have been in circles between Facebook's documentation and the wise sage of Stack Overflow and I'm at my wit's end. I think my problem lies in not being able to generate a "long-lived" access token, but I have to be able to do this without the client having to log-in to Facebook every time (or at all, for that matter). So how do other apps like those that mirror a user's Twitter status to Facebook handle offline posting with no subsequent user login/authentication?
I noticed that my code works if I use Facebook's Graph API Explorer. But that requires me to see a dialogue and this will not work in my client's case. (Login/Re-Authentication was NEVER needed a few months ago.)
I have been pulling my hair out for the past week trying to find the answer, and I keep going in circles:
https://developers.facebook.com/blog/post/2011/05/13/how-to--handle-expired-access-tokens
https://developers.facebook.com/roadmap/offline-access-removal
Facebook API: How to post to own application wall without login
http://facebook.stackoverflow.com/questions/11839544/how-to-avoid-fatal-error-uncaught-oauthexception-when-using-cron-job
...to name a few. I feel like a spider trapped in a bathtub.
If someone could share a practical code example that suits my particular case, that would be tremendously appreciated, thanks. Here is the code that was working that I have tried to adapt to the latest Facebook PHP SDK and protocols:
<?php
require_once 'facebook.php';
$facebook_access_token_url = "https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id=" . FACEBOOK_APP_ID . "&client_secret=" . FACEBOOK_APP_SECRET;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $facebook_access_token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$facebook_access_token = curl_exec($ch);
curl_close($ch);
$config['appId'] = FACEBOOK_APP_ID;
$config['secret'] = FACEBOOK_APP_SECRET;
$config['fileUpload'] = false; // optional
$facebook = new Facebook($config);
$facebook->setAccessToken($facebook_access_token);
$page_id = FACEBOOK_APP_PAGE_ID;
$facebook_access_token = "";
$result = $facebook->api('/' . FACEBOOK_ACCOUNT_ADMIN_ID . '/accounts');
foreach($result['data'] as $page){
if($page['id'] == $page_id) {
$facebook_access_token = $page['access_token'];
break;
}
}
$facebook->setAccessToken($facebook_access_token);
$attachment = array(
'access_token' => $facebook_access_token,
'message' => 'Test message',
'scope' => 'manage_pages,publish_stream,publish_actions'
);
$result = $facebook->api('/' . $_GET['post_id'] . '/comments', 'post', $attachment);
?>
If you get the page access token using a long-lived user access token, the page token will not expire by default – so offline_access deprecation is no actual problem in such a scenario.

Categories