Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook PHP / JS Sdk This authorization code has been used error

I am using Facebook php an js sdk.

I am login to facebook with js sdk. Login works perfectly.

and I have php part.

private $helper, $api_id, $app_secret, $session;        

....

FacebookSession::setDefaultApplication($this->api_id, $this->app_secret);
$this->helper = new FacebookJavaScriptLoginHelper();


try {
    $this->session = $this->helper->getSession();
} catch (FacebookRequestException $ex) {
    log_message('error', 'Facebook e1 :' . $ex->getCode());
    log_message('error', 'Facebook e1 :' . $ex->getMessage());
} catch (\Exception $ex) {
    log_message('error', 'Facebook e2 :' . $ex->getCode());
    log_message('error', 'Facebook e2 :' . $ex->getMessage());
}

if ($this->session) {
    $request = (new FacebookRequest($this->session, 'GET', '/me'))->execute();
    $user = $request->getGraphObject()->asArray();
    return $user;
} else {
    return false;
}

when page loads normally, I get user data without a problem.

But for example, if I press several times f5, to refresh page, I get and error that "This authorization code has been used." or "This authorization code has expired." and user data is empty.

Idea is to login with js, and to use php part to validate is user logged in into facebook or not.

I am using latest facebook php sdk : https://github.com/facebook/facebook-php-sdk-v4

Thank you.

like image 971
user147 Avatar asked Sep 27 '14 12:09

user147


Video Answer


1 Answers

There are several ways how to fix this.

1) You have to update the access token in the cookie every call, FB does not do this automatically. So, be sure you call the FB.init with status: true param.

    FB.init({
        appId      : window.fbId,
        cookie     : true,
        status     : true,
        version    : 'v2.3'
    });

Next, every page refresh you have to call FB.getLoginStatus(); no matter if you are connected to Facebook already.

This does not work if your application needs to do some ajax calls - simply because the access token is not updated when you do ajax (unless you call FB.getLoginStatus(); before every ajax call - and that's overkill).

2) Better may be to store the access token in session once user connect via FB JS SDK. The PHP code might look like this:

    try {
        $fbToken = isset($_SESSION['fbToken']) ? $_SESSION['fbToken'] : NULL;
        if ($fbToken !== NULL) {
            $session = new \Facebook\FacebookSession($fbToken);
        } else {
            $helper = new FacebookJavaScriptLoginHelper();
            $session = $helper->getSession();
        }

    } catch(\Facebook\FacebookRequestException $ex) {
        log_message('error', 'Facebook e1 :' . $ex->getCode());
        log_message('error', 'Facebook e1 :' . $ex->getMessage());
    } catch(\Exception $ex) {
        log_message('error', 'Facebook e2 :' . $ex->getCode());
        log_message('error', 'Facebook e2 :' . $ex->getMessage());
    }

    if ($session) {
        $accessToken = $session->getAccessToken();
        $longLivedAccessToken = $accessToken->extend();
        $_SESSION['fbToken'] = $longLivedAccessToken;
        $request = (new FacebookRequest($session, 'GET', '/me'))->execute();
        $user = $request->getGraphObject()->asArray();
        return $user;
    } else {
        return FALSE;
    }
}

Hope I did help... Cheers.

like image 193
Johnny Vietnam Avatar answered Jan 04 '23 12:01

Johnny Vietnam