Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook: "This authorization code has been used.","type":"OAuthException","code":100

I just upgraded to PHP 5.4.19 and facebook-php-sdk-v4.

Is it just me or has FB made the integration deliberately difficult?! For instance, I don't use Composer (can't install it on my shared host) so loading the new classes required a specific (discover-for-yourself) ordering - that was enough headache! The suggested solution at http://metah.ch/blog/2014/05/facebook-sdk-4-0-0-for-php-a-working-sample-to-get-started/ wasn't completely correct.

Anyway, when I finally got it to run and enabled "App Secret Proof for Server API calls" under the App advanced settings tab as recommended by Facebook I got into a catch 22.

This is it:

1) To make an FB API call from my server, e.g. $request = new FacebookRequest($session, 'GET', '/me'); I must now provide an appsecret_proof argument.

2) To create an appsecret_proof I need an access_token i.e. $appsecret_proof= hash_hmac('sha256', $access_token, $app_secret);.

3) To get an access_token with only $_GET['code'] at this point, I must do code exchange via GET https://graph.facebook.com/oauth/access_token? client_id={app-id} &redirect_uri={redirect-uri} &client_secret={app-secret} &code={code-parameter}.

4) To call FB for code exchange I get the error {"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100}}.

Two questions arise therefore:

1) How else can I get an access_token except via code exchange, so that I can use that token to create an appsecret_proof and in turn call FacebookRequest?

2) Where/How do I put that appsecret_proof into FacebookRequest? Is it perhaps this way $request = new FacebookRequest($session, 'GET', '/me', array("appsecret_proof" => $appsecret_proof));? I cannot seem to find the specific instruction on how to use appsecret_proof with PHP API (it is clear how to do it via http with Graph API).

like image 702
EdNdee Avatar asked Jun 04 '14 14:06

EdNdee


1 Answers

Ladies and Gentlemen, I resolved it all - I just needed to use $access_token = $session->getToken();. This helped me negate the call for code exchange which was causing OAuthException because Facebook has since changed their policy on the exchange code from being used more than once.

Now "App Secret Proof for Server API calls" is properly enabled under the App advanced settings tab as recommended by Facebook.

So the specific solution in complete:

$app_id = 'APPID'; $app_secret = 'APPSECRET';
FacebookSession::setDefaultApplication($app_id, $app_secret);
$redirect_url = "https://mydomain.com/login";
$helper = new FacebookRedirectLoginHelper($redirect_url);

try {
    $session = $helper->getSessionFromRedirect();
} catch (FacebookRequestException $ex) {
} catch (Exception $ex) {
}

if (isset($session)) {
    $access_token = $session->getToken();
    $appsecret_proof = hash_hmac('sha256', $access_token, $app_secret);
    $request = new FacebookRequest($session, 'GET', '/me', array("appsecret_proof" =>  $appsecret_proof));
    $response = $request->execute();
    $graphObject = $response->getGraphObject();

   echo print_r($graphObject, 1);
} else {
    echo '<a href="' . $helper->getLoginUrl() . '">Login</a>';
}
like image 170
EdNdee Avatar answered Sep 30 '22 11:09

EdNdee