'OAuth2 Token PHP

I need to connect with an API that is using oAuth2. I have never used oAuth2 before and im not really sure how to. The provider is giving this information:

Obtaining an access token is done by sending an HTTP POST request to the above endpoint. The request should contain the following headers:

Authorization: Basic [client_id]:[client_secret]
Content-Type: application/x-www-form-urlencoded

Where [client_id] and [client_secret] should be replaced with your information. The composed [client_id]:[client_secret] string should be base64 encoded.

The header should look something like this:

Authorization: Basic bXlfY2xpZW50X2lkOnBFUnkyTGhLYko0U2FkY3ZLcklpQW5xWnprakg5bm9STUc3aUxZcWl2MA==

Finally, you need the following request body:

grant_type=password&scope=read write&username=[username]&password=[password]

Where [username] and [password] should be replaced with your credentials. If you are accessing the API with an API-key you should replace both [username] and [password] with the API-key obtained above.

If your request was composed correctly, and your credentials were correct, the server will return an access_token in JSON format for you to use:

{
    "access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9(...)",
    "token_type":"Bearer",
    "expires_in":3600,
    "refresh_token":null
}

What I tried is the following, but it returns an invalid request message:

    $api = "KEY GOES HERE";
$authurl = "https://url.com/oauth/token";

$client_id = "ID GOES HERE";
$client_secret = "SECRET GOES HERE";

// Creating base 64 encoded authkey
$Auth_Key = $client_id.":".$client_secret;
$encoded_Auth_Key=base64_encode($Auth_Key);

$headers = array();
$headers['Authorization'] = "Basic ".$encoded_Auth_Key;
$headers['Content-Type'] = "application/x-www-form-urlencoded";

$data = "grant_type=password&scope=read write&username=".$api."&password=".$api."";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $authurl);
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

$auth = curl_exec( $ch );

if ( curl_errno( $ch ) ){
    echo 'Error: ' . curl_error( $ch );
}
curl_close($ch);

$secret = json_decode($auth);
$access_key = $secret->access_token;


Solution 1:[1]

All your code looks good except the POST field data. The problem is that your query string is already encoded. When you call curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));, then it is encoded again.

I recommend you to set the variable $data as an array:

$data = array(
    'grant_type' => 'password',
    'scope'      => 'read write',
    'username'   => $api,
    'password'   => $api,
);

The query string will be correctly encoded when http_build_query is called.

Solution 2:[2]

It worked for me. Please try with this piece of code to get token:

$base_url = 'https://example.com/oauth/token';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $base_url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
        'client_id'     => YOUR-CLIENT-ID,
        'client_secret' => YOUR-CLIENT-SECRET,
        'username'      => YOUR-USERNAME-OR-EMAIL,
        'password'      => YOUR-PASSWORD,
        'grant_type'    => 'password'
));

$data = curl_exec($ch);

$auth_string = json_decode($data, true); // token will be with in this json

After getting the access token, you have to use this token in the header for your next request. It can be get, post, put or something else.

GOOD LUCK

Solution 3:[3]

OAuth2.0 works on very simple principle, Hit the OAuth server get the token, pass the token to Resource server, Resource server validates the token and give the details/data.

So, to get the token check the following piece of code

$ch_curl = curl_init();
curl_setopt($ch_curl, CURLOPT_URL, "endpoint url");
curl_setopt($ch_curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch_curl, CURLOPT_POSTFIELDS, "grant_type = your grant_type");
curl_setopt($ch_curl, CURLOPT_POST, 1);   
 
$headers = array(); 
$headers[] = "Accept: application/json";
// base64_encode client id and password
$headers[] = "Authorization: Basic ABCDEFGHIJKLM123456"; 
$headers[] = "Content-Type: application/x-www-form-urlencoded";
curl_setopt($ch_curl, CURLOPT_HTTPHEADER, $headers);

$token = curl_exec($ch_curl);
echo $token;
curl_close($ch_curl);

which will return the response which you're looking it.

Solution 4:[4]

Combining all the answers here led me to this working code.

The token will be in the $auth array

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $base_url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(        
    'grant_type'    => 'client_credentials',    # https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/        
    'scope'         => $scope,  
)));

$headers[] = "Authorization: Basic " . base64_encode($client_id . ":" . $client_secret);
$headers[] = "Content-Type: application/x-www-form-urlencoded";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$data = curl_exec($ch);
$auth = json_decode($data, true); // token will be with in this json

var_dump( $auth );

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 MD. Shafayatul Haque
Solution 3 Matthew Lock
Solution 4 Matthew Lock