Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8024005
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T22:44:06+00:00 2026-06-04T22:44:06+00:00

I am trying to use a stored long-life access token, but after 2 hours

  • 0

I am trying to use a stored long-life access token, but after 2 hours I get the below error from the graph API. I have written some code to send the user to Facebook to get a new code that can be exchanged for an access token, which works just fine except this happens on every subsequent page request, Facebook continues to invalidate my access token with the below error, despite that access token being returned by their server.

Error validating access token: Session has expired at unix time 1338300000. The current unix time is 1338369365.

The complete test page example is below. Omitting my keys for obvious reasons. Hit the page, login and then leave it for a few hours and hit the page again (you’ll get the redirect to facebook and back with the code in the url), reload the page and it will continue to redirect to facebook and back, event though I am telling it to use the access token it just returned for said code.

<?php
  require 'facebook.php';

  $app_id = APP_ID;
  $app_secret = APP_SERCRET;
  $my_url = URL;

  $facebook = new Facebook(array(
    'appId'   => $app_id,
    'secret'  => $app_secret
  ));

  // known valid access token stored in a database
  $access_token = isset($_COOKIE["FB_LONG_AC_TOKEN"]) ? $_COOKIE["FB_LONG_AC_TOKEN"] : false;

  $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."<br />");
    echo($access_token."<br />");

    // Attempt to convert access token to longlife token if we don't have one stored.
    if (!isset($_COOKIE["FB_LONG_AC_TOKEN"]))
    { // don't have long life token, so let's get one.
      $ch = curl_init("https://graph.facebook.com/oauth/access_token?client_id=".$app_id."&client_secret=".$app_secret."&grant_type=fb_exchange_token&fb_exchange_token=".$access_token);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
      curl_setopt($ch, CURLOPT_TIMEOUT, 10);
      $data = curl_exec($ch);
      curl_close($ch);

      $params = null;
      parse_str($data, $params);

      if (isset($params["access_token"]))
      {
        $access_token = $params["access_token"];

        echo("Got long life token.<br />");
        setcookie("FB_LONG_AC_TOKEN", $access_token, time() + (3600 * 24 * 60), "/");
      }
    }
    else {
      echo("Have long life token already.<br />");
    }
  }

  if ($access_token) {
    $facebook->setAccessToken($access_token);

    // See if there is a user from a cookie
    $user = $facebook->getUser();

    if ($user) {
      try {
        // Proceed knowing you have a logged in user who's authenticated.
        $user_profile = $facebook->api('/me');
      } catch (FacebookApiException $e) {
        echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
        $user = null;
      }
    }
  }

  // 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;
  }
?>
<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
    <title>Facebook Auth</title>
</head>
<body>
  <?php if ($user) { ?>
    Your user profile is
    <pre>
      <?php print htmlspecialchars(print_r($user_profile, true)) ?>
    </pre>
  <?php } else { ?>
    <fb:login-button></fb:login-button>
  <?php } ?>

  <div id="fb-root"></div>
  <script>
      window.fbAsyncInit = function () {
        FB.init({
          appId: <?php echo($app_id); ?>,
          cookie: true, // enable cookies to allow the server to access the session
          oauth: true, // enable OAuth 2.0
          xfbml: true  // parse XFBML
        });

        FB.getLoginStatus(function (res) {
          console.log(res.status);
        });
      };

      (function(d){
        var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
        js = d.createElement('script'); js.id = id; js.async = true;
        js.src = "//connect.facebook.net/en_US/all.js";
        d.getElementsByTagName('head')[0].appendChild(js);
      }(document));
  </script>
</body>
</html>

What am I doing wrong? or this is a problem with Facebook?

UPDATE:

I have updated my code to follow the flow posted by @cpilko however I am still having the same problem. I can log in and out just fine. However if I visit the test page after some hours, say the next day I get the Session expired exception with the supplied long-life access token (FB JS SDK thinks I am connected, but the server did not), I refresh the page and I am shown as logged in by both the server and FB JS SDK and the long life token I get from facebook is the same as the one I original tried (stored in my cookies). What I don’t understand is why I am unable to use the long-life token the first time. Updated code below.

<?php
  require 'facebook.php';

  $app_id = "XXXXXXXXXXXXX";
  $app_secret = "XXXXXXXXXXXXXXXXXXXX";
  $my_url = "http://swan.magicseaweed.local/facebook/";

  $facebook = new Facebook(array(
    'appId'   => $app_id,
    'secret'  => $app_secret
  ));

  $valid_user = false;

var_dump($_COOKIE);
echo("<br />");

  if (isset($_COOKIE["FB_LONG_AC_TOKEN"]))
  { // Have long term token, attempt to validate.
    // Attempt to query the graph:
    $graph_url = "https://graph.facebook.com/me?"
      . "access_token=" . $_COOKIE["FB_LONG_AC_TOKEN"];
    $response = curl_get_file_contents($graph_url);
    $decoded_response = json_decode($response);

    // If we don't have an error then it's valid.
    if (!$decoded_response->error) {
      $valid_user = true;
      $access_token = $_COOKIE["FB_LONG_AC_TOKEN"];
      echo("Have long life token.<br />");
    }
    else {
      // Stored token is invalid.
      // Attempt to renew token.

      // Exchange short term token for long term.
      $ch = curl_init("https://graph.facebook.com/oauth/access_token?client_id=".$app_id."&client_secret=".$app_secret."&grant_type=fb_exchange_token&fb_exchange_token=".$facebook->getAccessToken());
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
      curl_setopt($ch, CURLOPT_TIMEOUT, 10);
      $data = curl_exec($ch);
      curl_close($ch);

      $params = null;
      parse_str($data, $params);

      if (isset($params["access_token"]))
      {
        $access_token = $params["access_token"];

        echo("Got long life token.<br />");
        setcookie("FB_LONG_AC_TOKEN", $access_token, time() + (3600 * 24 * 60), "/");
      }
      else
      { // Clear invalid token.
        setcookie("FB_LONG_AC_TOKEN", "false", time() - 3600, "/");
        echo("Long life token invalid.<br />");
      }
    }
  }
  else if ($facebook->getUser())
  { // Have short term access token.
    // Verify short term token is valid still.
    try {
        // Proceed knowing you have a logged in user who's authenticated.
        $user_profile = $facebook->api('/me');
    }
    catch (FacebookApiException $e) { }

    if (is_array($user_profile)) { // Have user.
      $valid_user = true;

      // Exchange short term token for long term.
      $ch = curl_init("https://graph.facebook.com/oauth/access_token?client_id=".$app_id."&client_secret=".$app_secret."&grant_type=fb_exchange_token&fb_exchange_token=".$facebook->getAccessToken());
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
      curl_setopt($ch, CURLOPT_TIMEOUT, 10);
      $data = curl_exec($ch);
      curl_close($ch);

      $params = null;
      parse_str($data, $params);

      if (isset($params["access_token"]))
      {
        $access_token = $params["access_token"];

        echo("Got long life token.<br />");
        setcookie("FB_LONG_AC_TOKEN", $access_token, time() + (3600 * 24 * 60), "/");
      }
    }
  }

  if ($access_token) {
    $facebook->setAccessToken($access_token);

    // See if there is a user from a cookie
    $user = $facebook->getUser();

    if ($user) {
      try {
        // Proceed knowing you have a logged in user who's authenticated.
        $user_profile = $facebook->api('/me');
      } catch (FacebookApiException $e) {
        echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
        $user = null;
      }
    }
  }

  // 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;
  }
?>
<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
    <title>Facebook Auth</title>
</head>
<body>
  <?php if ($user) { ?>
    Your user profile is
    <pre>
      <?php print htmlspecialchars(print_r($user_profile, true)) ?>
    </pre>
  <?php } else { ?>
    <fb:login-button></fb:login-button>
  <?php } ?>

  <div id="fb-root"></div>
  <script>
      window.fbAsyncInit = function () {
        FB.init({
          appId: <?php echo($app_id); ?>,
          cookie: true, // enable cookies to allow the server to access the session
          oauth: true, // enable OAuth 2.0
          xfbml: true  // parse XFBML
        });

        FB.getLoginStatus(function (res) {
          console.log(res.status);
        });
      };

      (function(d){
        var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
        js = d.createElement('script'); js.id = id; js.async = true;
        js.src = "//connect.facebook.net/en_US/all.js";
        d.getElementsByTagName('head')[0].appendChild(js);
      }(document));
  </script>
</body>
</html>
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T22:44:07+00:00Added an answer on June 4, 2026 at 10:44 pm

    The reason you get stuck in the loop when your original token expires is your code isn’t allowing Facebook to give you a new token. When you get an OAuth error, you are invoking the OAuth dialog, which doesn’t repopulate your cookie with a fresh token.

    The other problem you have is you’re overwriting the long-term access token with your short term access token before making an api call:

    // known valid access token stored in a database
    $access_token = isset($_COOKIE["FB_LONG_AC_TOKEN"]) ? $_COOKIE["FB_LONG_AC_TOKEN"] : false;
     ...
    if ($access_token) {
    $facebook->setAccessToken($access_token); //Loads the short-term token from a cookie!
    

    If it were my code, I’d use two variables: $access_token_temp and $access_token_long just so I could keep things straight.

    EDIT

    Your workflow on page load needs to be:

    + IF one exists, retrieve the long-term token from `$_COOKIE['FB_LONG_AC_TOKEN']` 
        + If it does exist, test to see if it is valid.
        + If valid, use the renew the token and update the cookie if one is returned. (Only one token will be returned per day)
        + Else mark the long-term token as invalid and clear the cookie.
        + Set a `$vaild_user` flag.
    + ELSE IF a new short-term token is available
        + Read the short-term token cookie with the PHP API and exchange this for a long-term token.
        + Store the long-term token in the cookie
        + Clear the short-term token cookie
        + Set a `$valid_user` flag
    + ELSE: The token does not exist or is invalid
        + Redirect the user to the JS API auth dialog and store the returned short term token in a cookie.
        + Reload the page to process this.
    + ENDIF 
    + IF `$valid_user`: Do stuff.
    

    You’ve got all the parts in your code. You just need to clean up the logic to make it work.

    Edit #2:

    I ran your code on my server. It mostly works, but the debugging information you’re outputting is sending headers prematurely, inhibiting the ability of setcookie() to set a cookie.

    I got your code to run by declaring $out = array(); near the beginning, then by changing all your echo and print statements to $out[] = "What you were echoing or printing before"; To still display this, add echo implode("\n", $out); within the <body> of your document.

    Once I did that, I was able to store a valid token in a cookie, and validate that it is indeed a long-life token with a 60-day expiration.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am trying to use the stored procedure mapping feature in Entity Framework to
For a Gridview: I am trying to use a stored procedure for the first
I'm trying to use a PEM(X.509) certificate (stored in a privateKey.pem file on disk)
So, I'm trying to use ODBC to execute a stored procedure in an SQL
I am trying to track down why a string is stored so long in
I have been trying to use the UISaveVideoAtPathToSavedPhotosAlbum to save my video (stored locally
I'm trying to use the SetupDiGetDeviceProperty, but apparently it couldn't find such functions within
I am for a long time trying to get a picture how is program
So, I'm trying to use ADO.NET to stream a file data stored in an
im trying to use direct store in Extjs heres the code to my store

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.