Search code examples
phpoauth-2.0oauth2client

Exchange the Authorization Code for an Access Token In OAuth 2.0


I am trying to exchange the authorization code (which is in the url of this page) for an access token using oAuth 2.0.

I am running the following php code and am getting an error (http error 500).

I can't figure out what is wrong with the following code. I have deleted the actual client id, etc- it's there to show the code:

<?php
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://id.shoeboxed.com/oauth/token",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"grant_type\":\"authorization_code\",\"client_id\": \"f8de67be8dc84e449203fcdd4XXXXXXX\",\"client_secret\": \"HS5ZeIVsKW0/qqiO9/XcdeWqnF8vtzQrpY8gcdrxg0BXNZXXXXXXX\",\"code\": \"['code']\",\"redirect_uri\": \"http://website.com/foursquare2.php"}",
  CURLOPT_HTTPHEADER => array(
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
?>

Solution

  • The json string you have in your post fields is not a valid json string. You can test json here:

    https://jsonlint.com/

    You might try populating an array with your post fields, then use json_encode() to encode the array to a json sting in your curl request. This will help mitigate errors when creating your json string. I greatly prefer doing it this way.

    $postArray = array(
    
          'grant_type' => 'authorization_code',
          'client_id' => 'f8de67be8dc84e449203fcdd4XXXXXXX',
          'client_secret' => 'HS5ZeIVsKW0/qqiO9/XcdeWqnF8vtzQrpY8gcdrxg0BXNZXXXXXXX',
          'code' => '[\'code\']',
          'redirect_uri' => 'http://website.com/foursquare2.php'
    
    );
    
    
    $curl = curl_init();
    
    curl_setopt_array($curl, array(
      CURLOPT_URL => "https://id.shoeboxed.com/oauth/token",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_SSL_VERIFYPEER => false, //<--- Added this.
      CURLOPT_ENCODING => "",
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => "POST",  //<---You may also try "CURLOPT_POST => 1" instead.
      CURLOPT_POSTFIELDS => http_build_query($postArray), //<--Makes your array into application/x-www-form-urlencoded format.
      CURLOPT_HTTPHEADER => array(
        "application/x-www-form-urlencoded" //<---Change type
      )
    ));
    
    $response = curl_exec($curl);
    $err = curl_error($curl);
    
    curl_close($curl);
    
    if ($err) {
      echo "cURL Error #:" . $err;
    } else {
      echo $response;
    }
    

    Your new error is a result of not having the appropriate certificates installed on your server. Here is a link to get you started, if it don't help, SO and google have a bunch of stuff on this.

    How do I deal with certificates using cURL while trying to access an HTTPS url?

    I added CURLOPT_SSL_VERIFYPEER => false to your options array. This is a bandaide until you can get your certificate problem figured. It does potentially expose your data to someone who may be snooping.

    Your third issue has to do with the type/format of the data that you are sending to the data to. It's expecting application/x-www-form-urlencoded and you have stated your content type as application/json.

    Here is some reading on the subject:

    How are parameters sent in an HTTP POST request?

    application/x-www-form-urlencoded or multipart/form-data?