My app is not loaded and I get the erro below in these two scenarios:
a) The first time I access my app after clearing cache & cookies, or from a PC I haven't used before, with any browser.
b) When USER A tries to access the app straight after USER B has logged out from the app (and Facebook), from the same PC and browser, without clearing cache or cookies.
However, when I press F5 to update the webpage, it is working properly.
This is the error I get on the log file:
{"readyState":4,"responseText":"Invalid access token","status":200,"statusText":"OK"}
User validation code:
require_once(dirname(__DIR__).'/lib/common/AppInfo.php');
require_once(dirname(__DIR__).'/sdk/src/facebook.php');
require_once(dirname(__DIR__).'/lib/logic/UsersLogic.php');
require_once(dirname(__DIR__).'/lib/common/Log.php');
if (substr(AppInfo::getUrl(), 0, 8) != 'https://' && $_SERVER['REMOTE_ADDR'] != '127.0.0.1') {
header('Location: https://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit();
}
try {
$facebook = new Facebook(array(
'appId' => AppInfo::appID(),
'secret' => AppInfo::appSecret(),
));
$user_id = $facebook->getUser();
} catch (Exception $e) {
exit("Error getting facebook data");
}
if ($user_id) {
try {
$basic = $facebook->api('/me');
} catch (FacebookApiException $e) {
if (!$facebook->getUser()) {
exit("Invalid access token");
}
}
if($basic==null){
exit("Application not installed");
}
$user=UsersLogic::getUser($user_id);
if($user==null){
exit("User not registered in database");
}
}
else{
exit("No user logged");
}
Any ideas why does it happen? Perhaps I should force to request a new user access token? (how)
THANKS
This is totally expected - in the first scenario there are not cookies, no knowledge of who the user is, and hence no way of getting hold of a valid access token, and in the second scenario, logging out from Facebook (or de-authorizing your app) will cause any access tokens you have to be invalidated.
But that error, that is from the client side code right?
In that case, you need to wrap the code you're using with FB.getLoginStatus or similar so that you don't run it unless you actually have the needed access token.
Related
I have problem with authorization of my facebook application. When I run my application normally on my local web server process goes like this:
**Get facebook user->If user is not logged on -> Redirect user on facebook login page**
**Get facebook user->If user is logged on -> Redirect user to authorize my facebook application->everything goes right without problems**
When I host my application on facebook using iframe, second process is not working (user never get show the authorization window), and I get following exception:
Error validating access token: User xxxxxxx has not authorized application xxxxxxx.
I'm using CodeIgniter PHP framework, and this is my PHP code:
$this->load->library('facebook');
$user = null;
$user_profile = null;
$user = $this->facebook->getUser();
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$access_token = $this->facebook->getAccessToken();
$user_profile = $this->facebook->api($user);
}
catch (FacebookApiException $e) {
show_error(print_r($e, TRUE), 500);
}
}
else{
$data = array(
'redirect_uri' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx','scope'=>'email');
$access_token = $this->facebook->getAccessToken();
redirect($this->facebook->getLoginUrl($data));
}
$data['facebook']=$user_profile;
$this->load->view('templates/header');
$this->load->view('pages/prijavaKlasicnoFacebook', $data);
$this->load->view('templates/footer');
}
You can not load the OAuth dialog in an iframe – security reasons.
You have to load it into the top-most window instance – so no server-side redirect, but a client-side “redirect” using top.location.href = "…";
Get your script to output this JS snippet (including the correct login URL) inside an otherwise empty document.
You should also provide "Read Stream" and "Publish Data" in your scope.
I'm working on a site that uses the Facebook PHP SDK. It is working great, and after 2 hours, whenever I try to get onto one of the general pages on the site, I get...
Fatal error: Uncaught OAuthException: An active access token must be used to query information about the current user.
If I go back to the index page, I get a new access token and everything works properly again...for 2 hours.
What code can I put on my webpages to redirect to the index page when the access token has expired?
Thanks for helping this noob.
You must redirect user to page that has authorized code.
If your user not deauthorized app , the Oauth dialog isn't appear.
For more information go to
Access Token & Handling
You can put a try / catch block in your code.
Put each Facebook API call in such block and if an exception occurs you can redirect the user to the right resource by header('Location: <url>');:
try {
# FB API call
}
catch(OAuthException e) {
header('Location: <url>');
}
Have a file that goes like this and include it in your webpages.
$facebook = new Facebook(array(
'appId' => "app id",
'secret' => "app secret",
));
$user = $facebook->getUser();
$loginUrl = $facebook->getLoginUrl();
if ($user) {
try {
$me = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
}
}
else {
echo "<script type='text/javascript'>top.location.href = '$loginUrl';</script>";
}
How are you supposed to deal with people who signed into Facebook a while ago. Come to your site you should them a continue link (because you detect that they are already logged into Facebook) and then on the page you direct them to you get this error.
Fatal error: Uncaught OAuthException: An active access token must be used to query information about the current user. thrown in /var/www/html/lib/base_facebook.php on line 1039
I don't understand how you are supposed to prevent this? Does this have something to do with the signed info that you give back to Facebook to get an access_token? Seems like this signed info can expire (it has an issued_at date). What is the correct way to handle this in your website's flow?
Are you expected to write code like this:
<?php
$user = $facebook->getUser();
try {
// attempt to do a call just to see if you are going to have this issue
$profile = $facebook->api('/me');
} catch (Exception $e) {
$user = false;
}
if ($user) { ?>
Begin
<?php } else { ?>
<fb:login-button scope="email" size="large">Connect</fb:login-button>
<?php } ?>
Instead of this:
<?php
$user = $facebook->getUser();
if ($user) { ?>
Begin
<?php } else { ?>
<fb:login-button scope="email" size="large">Connect</fb:login-button>
<?php } ?>
Getting the $user back from the Facebook SDK only seems to tell you there is a cookie. And not if that will actually work when you go to do the API calls.
UPDATE:
So my only problem with this method is ... when the user does have a cookie on my site, but the API call fails - I show them the connect button. User clicks the connect button, it quickly appears and disappears. Because it wasn't a true 'auth.login' that just occured, the user will not get sent to my start.php page via JavaScript redirect. How do others handle this? I'm stumped. Please tell me if there are other flaws with how I'm attempting to do this.
Try passing the access token to the API call that verifies that the user has authorized your application. Below is what I do, and it should help to alleviate the OAuthException you're getting.
$user = $facebook->getUser();
if($user) {
$access_token = $facebook->getAccessToken();
$params = array('access_token' => $access_token);
try {
$me = $facebook->api("/me", $params);
} catch(FacebookApiException $e) {
$user = null;
}
}
if($me) {
// proceed with authenticated user with an active access token.
}
Are you expected to write code like this:
Yes, you will have to handle the OAuthException.
But rather than using FBML login button, you can redirect the user to facebook login url for your application. You can get the url by using function getLoginUrl provided by Facebook PHP SDK. See getLoginUrl for more information.
For your email permissions you can use following array:
$params = array( 'scope' => 'email' );
Once successfully logged in, the user will be redirected back to the application page which redirected him to facebook login.
I'm using the PHP Facebook SDK (v.3.1.1) for building my Facebook app.
At some point in my flow I need the user to accept my app. I'm using the following code:
// Is there an error? Redirect to explain permissions page
if(!empty($_GET['error'])) {
$redirectUrl = APP_FACEBOOK_PAGE;
require_once(ABSOLUTE_DOCUMENTROOT_PATH.'do_redirect.inc.php');
die();
}
// Prepare app
$facebook = new Facebook(array(
'appId' => APP_ID,
'secret' => APP_SECRET,
'cookie'=> true
));
$facebookId = $facebook->getUser();
// Changed user?
if((!empty($_SESSION['facebookAuth']['facebookId']) && $_SESSION['facebookAuth'] ['facebookId'] != $facebookId)) {
$facebook->setAccessToken('');
$_SESSION['facebookAuth']['facebookId'] = $facebookId;
$redirectUrl = getRequestPermissionsUrl($facebook);
require_once(ABSOLUTE_DOCUMENTROOT_PATH.'do_redirect.inc.php');
die();
}
// No access token? Re-acquire it!
if($facebook->getAccessToken() == '') {
$redirectUrl = getRequestPermissionsUrl($facebook);
require_once(ABSOLUTE_DOCUMENTROOT_PATH.'do_redirect.inc.php');
die();
}
// Let's see if we have an active session
if(!empty($_SESSION['facebookAuth']['facebookId']) && !empty($_SESSION['facebookAuth'] ['facebookUserObject'])){
$facebookId = $_SESSION['facebookAuth']['facebookId'];
$facebookUserObject = $_SESSION['facebookAuth']['facebookUserObject'];
}else{
$facebookId = $facebook->getUser();
if ($facebookId) {
try {
$facebookUserObject = $facebook->api('/me');
// Put them in session so we can re-use them
$_SESSION['facebookAuth']['facebookId'] = $facebookId;
$_SESSION['facebookAuth']['facebookUserObject'] = $facebookUserObject;
} catch (FacebookApiException $e) {
error_log($e);
}
}
}
// If no facebookId -> check permissions anyway
if(empty($facebookId)) {
$redirectUrl = getRequestPermissionsUrl($facebook);
require_once(ABSOLUTE_DOCUMENTROOT_PATH.'do_redirect.inc.php');
die();
}
My function 'getRequestPermissionsUrl' calls for the getLoginUrl:
return $redirectUrl = $facebookObject->getLoginUrl(array('canvas'=>1,'fbconnect'=>0,'redirect_uri'=>$returnUrl,'scope'=>'publish_stream,email,user_likes'));
the file 'do_redirect.inc.php' does a js-redirect:
top.location.href = '$redirectUrl';
So, with that in mind let's take a look at the first part.
This code gets included again after the user has denied the permission and the page reloads. In that case $_GET['error'] is filled and we'll be redirected to another php-file in the app - a file that does not include the code I posted but has nothing to do with permissions or stuff at all. In that other file is a link to the page that needs permission again - the code above gets loaded again but when trying to request permissions I'm getting the error 'something went wrong and we're trying to fix it' on a Facebook page.
I've tried evertyhing from destroying sessions to setting the accestoken empty to... you name it. I'm quite out of ideas now so I'd be glad if somebody of you guys have any suggestions. Any help would be greatly appreciated.
Thanks in advance!
I just saw a newer question asking the same thing - Sorry, something went wrong after cancel application connexion on SDK 3.0
There is a currently open bug in Facebook's bug tracker about this
I've a facebook application, which conncets to facebook via the PHP-SDK.
$facebook = new Facebook(array(
'appId' => FACEBOOK_APP_ID,
'secret' => FACEBOOK_SECRET_KEY,
));
$user = $facebook->getUser();
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
Everything is fine, I let the browser open and don't respond to my app. After a while I try to send a form in the app via ajax. It seems that the session is invalid? Facebook will authorize my app again load the ajax url into the browsers address bar and attach the new session param to that url and breaks the app.
Is there anything I could do to pretend facebook to "reload" or pass the ajax/form action to the browser address bar? Before every request is processed I check whether the user is still active or not, that might be the problem?
$user = $facebook->getUser();
if ($user != 0) {
if($this->userProfile == null){
try {
// Proceed knowing you have a logged in user who's authenticated.
$this->userProfile = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
}else{
$this->userProfile = null;
}
if ($this->userProfile != null) {
$filterChain->run();
} else {
$loginUrl = $facebook->getLoginUrl(
array('scope' => 'publish_stream','redirect_uri' => 'REDIRECT_URI'));
}
echo("<script> top.location.href='" . $loginUrl . "'</script>");
Should I use an other approch?
Thanks in advance!
You really shouldn't be processing ajax calls the same way as regular page fetches. Generally if something like an expired session happens within an ajax process you want to send an error code back to the main page and let it handle it at the top level.
I'm guessing that the info you send back from this ajax request gets immediately parsed as HTML? Which means that if you send back a <script>top.location=xxx</script> block, it gets executed and redirects the browser to the new location. Again that's probably not the best way to handle things, but it would still work if the redirect_uri were set appropriately (to the url of the page as a whole). Because the getLoginUrl() is called while within the ajax page, the redirect_uri is set to that url instead, so after the new authorization is completed that's where the browser is sent back to (at the top level now). So while probably not the best overall structure, a quick workaround would be to override the redirect_uri setting when you are within an ajax call, and make it point to the parent page instead of itself.