The objective is extremely simple, yet there are no examples on how to retrieve the user token associated to the currently running app.
My objective is to just pull my public facebook page (business page with complete open access) with the app I have created in facebook that I mere created just to get an app id and secret so I can have PHP perform the request for the data and then iterate it on my homepage. Very simple, yet the documentation on the site mainly deals with facebook logins which I have no intention of doing. I just want my feeds from the public business page on the site.
This is where I think Facebook goes horribly wrong. Here is my code so far that queries properly but generates an empty data set:
$app_id = "APP_ID";
$app_secret = "APP_SECRET";
$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);
$params = null;
parse_str($response, $params);
$graph_url = "https://graph.facebook.com/202978003068170/feed?access_token=".$params['access_token'];
$app_details = json_decode(file_get_contents($graph_url), true);
echo '<pre>';
var_dump($app_details);
echo '<pre>';
Now let my clarify what the actual access_token value is because Facebook is vague ambiguous about this. There are actually two types of access tokens and the app I have created has both types which if you are logged in and working on your app you can see here:
https://developers.facebook.com/tools/access_token/
The major problem is the access_token value that oauth returns from the code above is the "App Token" which has no problem querying for User Profile data (which is kinda scary) but returns blank data when I try to query my Public business page {"data":[]} that I have enabled all the permissions for. After a week of trying out different methods and slamming my head on the desk and only finding partial salvation through third party sources of information did I figure out the difference between these two.
I have ran across a post on here that said I have to do a 2nd OAUTH query to pull the App's "user token" (which I have tested the user token associated to the app token from the token debugger in fbook and it works) to Facebook but what does that query consist.
Please someone help. This should not be this difficult, I am not wanting users to login to my site with fbook. I just want to display by business events, feeds and pictures on my business website.
Thank you
Related
I recently started playing around with Facebook graph API and wanted to integrate images pulled from my Facebook page to display on my website. I have the images displaying properly but my problem is whenever anyone tries to view the page they are asked to log into Facebook first. Is there any way to display the images without prompting the user to log into Facebook?
Here is what I am using to make the session:
$app_id = 'id';
$app_secret = 'secret';
$redirect = 'my webpage';
// init app with app id and secret
FacebookSession::setDefaultApplication($app_id,$app_secret);
// login helper with redirect_uri
$helper = new FacebookRedirectLoginHelper($redirect);
try {
$session = $helper->getSessionFromRedirect();
} catch( FacebookRequestException $ex ) {
// When Facebook returns an error
} catch( Exception $ex ) {
// When validation fails or other local issues
}
Any help would be appreciated.
Step one: familiarize yourself with the API. Read the docs, and play around with the Graph API Explorer
Step two: the code you provided has nothing to do with what you are trying to achieve (displaying page photos). That code is basically the getting started code used in the docs. If you need help, post the relevant code.
Step three: as mentioned by #CBroe, authenticating the visitor is not needed to display photos from a page. What you might want to explore:
The page admin authenticating your app with the right permissions (maybe manage_pages)
with the user access token you just got, you extend it to long-lived one
then you query the API to get a page access token that won't expire
you store this access token and query the API to get the relevant data and store it (GET /{PAGE-ID}/photos or GET /{PAGE-ID}/albums ... etc)
you show the stored data to your visitors
Notes:
Do not make these calls on client-side ... i.e. reveal your page access token, since you can do this in the backend.
Use the realtime updates to get notified when you should query the API and get new photos instead of periodically querying the API to pull new photos, or even worst, querying the API on each user visit.
I'm trying to retrieve an Access Token from Facebook using PHP SDK 3.2.2, being the code below what I placed in the redirect url after a sucessfull user login in Facebook. My problem is that $this->facebook->getAccessToken() is not giving back the user access token after the user gives access to the APP, just a string with the form: 'AppId|AppSecret', and I have to include code to manually get the User Access Token. This work, but I don't know WHY when I use getAccessToken is not giving back the right Token. I would also like to know how if there is any better way to retrieve User Access Token than with $code, because I don't feel this is a good way of doing it.
NOTE: I use $this->facebook because I load it as a Codeigniter library.
$access_token = $this->facebook->getAccessToken();
//-------------------------------------------------------------------------
//echo '<br/>Access Token: ' . $access_token;
// Generare Token if not created:
$code = $_REQUEST["code"];
if ( isset($code) ) {
//echo '<br/>Code Enviado: ' . $code;
//exit();
$appId = $this->facebook->getAppId();
$appSecret = $this->facebook->getAppSecret();
$redirectTo = base_url('asociar/acc_facebook/step2/');
$token_url="https://graph.facebook.com/oauth/access_token?client_id="
. $appId . "&redirect_uri=" . urlencode($redirectTo)
. "&client_secret=" . $appSecret
. "&code=" . $code . "&display=popup";
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$access_token = $params['access_token'];
//echo '<br/>Repitiendo el Token';
$this->facebook->setAccessToken($access_token);
//echo '<br/>Second Access Token Fijado: ' . $access_token;
}
//-----------------------------------------------------------------------
UPDATE:
This issue is due to I used CI with PHP SDK (check my own answer for that), but the answer is valid to anyone that have this issue with Facebook PHP SDK (Check #Imbru answer)
#Imbru pointed me in the solution, if any credit, give it to him.
Take this into account: when using Codeigniter, it saves all the session data in the cookie and send it to the browser, not storing it in the server. Yes, they do it, and it leads to many other problems (as losing of session when you store a lot of data, and the browser only sends you back part of them, but that is another history).
With CI, the solution is overwrite the session core class, with another session class which manages the session with PHP $_SESSION, as for example, https://bitbucket.org/xperez/core-session-storage-for-codeigniter (I use it in my projects, and work like a charm). In that way, when using PHP-sdk you'll save the values in the session, and when Facebook class will try to retrieve them back, it'll be able of doing it.
And of course, if you're having issues with the Facebook PHP SDK, check if $_SESSION is storing the values you want, as the problem is you don't have the value in the server when you want to retrieve it, leading you to an error of not authentication.
The response is little late, but may be it will help for other users.
I have got the same issue today.
My access_token was not correctly store in $_SESSION. Apparently, client side send juste one time the access_token. You have to store it in memory (SESSION) and reused it.
In normal time, Facebook PHP SDK do it...
EDIT : See #Chococroc response for more explanations
I'm creating a facebook app with facebook php adk 3.0.
I was able to do facebook connect login successfully as per the sample code from github.
the page to which i'm redirecting after facebook login is returning my correct user id using the function
$user = $facebook->getUser();
But if i go to any other page in the app, and if i call $facebook->getUser();, it's returning zero.
Seems like i should save logged in user session some where, anybody know solution for this?
After long search i found solution for this.
From the page to which u'll be redirected after facebook login, store access token in session.
$access_token = $facebook->getAccessToken();
$_SESSION['token'] = $access_token;
Then if you want to call a fb api from any other page, set access token as below before calling the api.
$access_token = $_SESSION['token'];
$facebook->setAccessToken($access_token);
Hope it will help.
In my canvas page, I try to authenticate the user the way it is described in http://developers.facebook.com/docs/guides/canvas/, by using essentially this code (example code from developers.facebook.com):
<?php
$app_id = "YOUR_APP_ID";
$canvas_page = "YOUR_CANVAS_PAGE_URL";
$auth_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page);
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $data["user_id"]);
}
?>
The problem is, the first time the user authorizes my canvas application, Facebook doesn't pass a signed_request parameter when redirecting back (as described in the example code), but a code parameter. When accessing the application the second time (already having confirmed the rights), it passes a signed_request parameter as expected.
Why does it pass a code parameter the first time? The documentation doesn't explain when Facebook passes a code / signed_request parameter.
The problem was that for $canvas_page, I used the canvas URL (e.g. mysite.com/canvas) instead of the canvas page URL (e.g. apps.facebook.com/myapp).
I think you need to append "&response_type=token" to your authentication url:
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&response_type=token
Then you get back something that looks like:
http://apps.facebook.com/APP_NAME/#access_token=YOUR_APP_ID%YADA_YADA_YADA0&expires_in=3948
And you can extract it with some Javascript:
if (window.location.hash.length == 1)
{
var accessToken = window.location.hash.substring(1);
}
Facebook uses the code parameter to authenticate your application. In the documentation, it states:
*If the user presses Allow, your app is authorized. The OAuth Dialog will redirect (via HTTP 302) the user's browser to the URL you passed in the redirect_uri parameter with an authorization code*
To complete the authorization, you must now take the code parameter and your app secret and pass it to the Graph API token endpoint (paraphrasing the documentation). This will grant you access to the access token. From this point onward, your application will not require the code parameter for this user because they are already authenticated.
Facebook uses the signed_request to share information with your application. The documentation states three scenarios in which it will pass the signed request. These are:
A signed_request is passed to Apps on Facebook.com when they are loaded into the Facebook environment
A signed_request is passed to any app that has registered an Deauthorized Callback in the Developer App whenever a given user removes the app using the App Dashboard
A signed_request is passed to apps that use the Registration Plugin whenever a user successfully registers with their app
So to conclude, the code parameter is only sent to authenticate the application, while the signed_request is utilized to pass information once the application has been authorized.
Saj-and is very correct.
I too struggeled with this alot.
When setting the redirect_uri to my domain name, I got an infinate redirect loop.
When setting the redirect_uri to the facebook app url, I got an error saying the url is not on my domain and so cannot be accessed.
It took the "/" at the end to solve this
I had the same problem with my canvas app, I fixed it by simply redirecting to my application's canvas url in the case that there is a code GET request parameter. After that Facebook sends me POST request that contains the signed_request parameter as expected. Here is the Python Django snippet:
if 'code' in request.GET.keys():
return HttpResponseRedirect(FACEBOOK_CANVAS_URL)
# ...rest of your canvas handling code here
I struggled with this issue (not getting oauth ID in the signed_request and instead get the "code" after user approves the app) for over a week, and this post (and few others posts) helped me get very close to resolving the issue (I was using my apps canvas URL instead of the canvas page url in the redirect URI, and I didn't specify the namespace in the settings).
After making these corrections, I faced a different issue where the app approval page won't show up for a new user and instead facebook throws the message" application has an error etc.. and finally I figured I was missing a / at the end of the canvas page url in my redirect url.. I had it as https://apps.facebook.com/myappname instead of https://apps.facebook.com/myappname/ in the redirect uri. Adding the / at the end resolved the issue and when a new user access my app using https://apps.facebook.com/myappname (if the user is already logged in ) facebook shows the approval page (upon receiving the response from my server) and once the user approves the app, facebook sends the signed-request with the required auth code to my application. Hope this will be useful for anyone else who might encounter the same issue.
Just to clear the confusion about the code parameter.. Facebook will always send this parameter when user allows the application.. however the signed_request parameter is sent using post or some other method.. it is not sent in the url.. You can access it using $_REQUEST['signed_request']
I had a similar problem that was solved when I assigned a namespace to my app, so it would look like apps.facebook.com/myapp and not apps.facebook.com/1234.
I was experiencing the problem you describe with firefox and with third-party cookies disabled.
I enabled third-party cookies and then the signed_request was suddenly available.
My site utilizes lifetime access tokens (offline_access). However, if the user changes his/her password, the access token gets reset. Is there a method to check if the current access token is valid before making calls to the Graph API? Thanks for your time.
Offline, without sending anything to facebook - I don't think so. The easiest way is probably to send a request to:
https://graph.facebook.com/me?access_token=...
Facebook also supports subscriptions for real-time updates, but I am not sure how to apply them to this situation.
If you want to know the token expiry time you can pass a open graph url using appid and token as below it will work .
https://graph.facebook.com/oauth/access_token_info?client_id=APPID&access_token=xxxxxxxxx
Basically, FB wants you to poll for it, or to detect the case and redirect the user to get a reauth to occur. Annoying, but official:
(Old, out of date link. See below) https://developers.facebook.com/blog/post/500/
Edit: Facebook changed their link structure without redirects. Not surprised.
https://developers.facebook.com/blog/post/2011/05/13/how-to--handle-expired-access-tokens/
You can check the token using the token debug service , take a look here
https://graph.facebook.com/debug_token?input_token=INPUT_TOKEN&access_token=ACCESS_TOKEN
https://developers.facebook.com/docs/howtos/login/debugging-access-tokens/
The real time updates would allow you to solve this problem, but it would be pretty complicated. Basically, you can subscribe to updates that will tell you 1) if the user removed the app or 2) if the user removed permissions. You could use this to store the current permissions of the faceboook user. This way, if the user removed your app you would know that the access token is expired.
Real time updates is actually facebooks recommended way of handling permissions. Many apps make api calls every time a page is loaded to check for permissions. This tends to be slow and unreliable.
I went through these posts, bud I found very good solutions like this:
GET graph.facebook.com/debug_token?
input_token={token-to-inspect}
&access_token={app_id}|{app_secret}
Response from this request provides you everything you need:
your app ID - this verifies that token is from your application
application name - which can be also checked
expires_at - token expiration time
is_valid - boolean for check up
user_id - which you can also compare and check
Just note that "|" sign must be there as a letter
//When user access token expires user must be logged in and renew the access token him self.it is a Facebook policy
//you can overcome this by sending email to users who have expired access token.
//create a table of successful sending to monitor sending process
//if any failure happened with the user an email is sent to him to ask him to activate there account again.with a link to your subscription page.
//and here is the code should be written on that page.
$app_id = "YOUR_APP_ID";
$app_secret = "YOUR_APP_SECRET";
$my_url = "YOUR_POST_LOGIN_URL";
// known valid access token stored in a database
$access_token = "YOUR_STORED_ACCESS_TOKEN";
$code = $_REQUEST["code"];
// If we get a code, it means that we have re-authed the user
//and can get a valid access_token.
if (isset($code)) {
$token_url="https://graph.facebook.com/oauth/access_token?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret
. "&code=" . $code . "&display=popup";
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$access_token = $params['access_token'];
}
// Attempt to query the graph:
$graph_url = "https://graph.facebook.com/me?"
. "access_token=" . $access_token;
$response = curl_get_file_contents($graph_url);
$decoded_response = json_decode($response);
//Check for errors
if ($decoded_response->error) {
// check to see if this is an oAuth error:
if ($decoded_response->error->type== "OAuthException") {
// Retrieving a valid access token.
$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>");
}
else {
echo "other error has happened";
}
}
else {
// success
echo("success" . $decoded_response->name);
echo($access_token);
}
// note this wrapper function exists in order to circumvent PHP's
//strict obeying of HTTP error codes. In this case, Facebook
//returns error code 400 which PHP obeys and wipes out
//the response.
function curl_get_file_contents($URL) {
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_URL, $URL);
$contents = curl_exec($c);
$err = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
if ($contents) return $contents;
else return FALSE;
}
Offline - it is not possible
Ask that user has given permission or not:
https://graph.facebook.com/{facebook-id}/permissions?access_token={access-token}
If access token is invalid then it will give error:
{
error:{
message:"The access token could not be decrypted",
type:"OAuthException",
code:190
}
}
Otherwise it will give list of permission that user has given:
data:[
{
installed:1,
...... permission list.........
bookmarked:1
}
]
Updating this as things have changed since OP:
You can debug access tokens here: https://developers.facebook.com/tools/debug/accesstoken?version=v2.5&q={access_token}
Otto's answer of the facebook post seems to be the official response on this question, however it uses straight PHP instead of the SDK and also uses JS to resolve the issue instead of PHP. If you are using PHP to check for a valid session you often need a PHP method of ensuring a valid session in order to continue.
The following code checks for the me object with the graph API. If an exception is thrown it destroys* the current Facebook session.
try{
$facebook->api('/me');
}
catch( FacebookApiException $e ){
$facebook->destroySession();
}
This forces later graph calls to instantiate a new Facebook session. This at least gives you access to public data so that you can render pages do not require FB user permissions:
$facebook->api('/userName');
To reobtain user permission access the user will need to login to your app (this is distinct from being logged into Facebook itself). You can do this with JS or with PHP:
$facebook->getLoginUrl();
*Note the destroySession() call is not in a tagged release of the PHP SDK yet. Use the master branch or patch it in.