Terug naar alle berichten
PHP cURL API calls with authentication (REST GET POST)
Development

PHP cURL API calls with authentication (REST GET POST)

Geupdate op februari 8, 2024

If you’re here because you want to connect your php code to an external API, please check my cURL api-calls with php tutorial first. This is part 2 of how to connect to an API using cURL in php, as I received a lot of questions on how to connect if the API requires authentication (utoken) first.

Heads up: This time, I will be using Javascript for more flexibility. As I need to make an ‘authentication’ api call first before our initial GET call. Therefore I create my API calls in my own php files on the side, and will target these files using ES6 async/fetch from within my page. If you see me linking to my-site.com, this means I created the file myself, on my own server. If I’m linking to api-site.com, this means I’m making a call the the external API.

cURL Authentication

Generating an auth key

Some API’s only allow POST or GET requests if you use an auth-token. We need to generate this auth-token first, before we are allowed to make API calls. Normally the API docs should explain how you can generate their auth-token. In my example, I can generate an auth-token by posting my API client ID, client_secret and a login type to their API Auth file.

Here is how I can generate and use my auth-token, based on the cURL script of my part-1 tutorial. In this tutorial, I’ll be calling this file api/auth.php

$curl = curl_init();
$auth_data = array(
	'client_id' 		=> 'XBnKaywRCrj05mM-XXX-6DXuZ3FFkUgiw45',
	'client_secret' 	=> 'btHTWVNMUATHEnF-XXX-2nQabKcKVo3VXtU',
	'grant_type' 		=> 'client_credentials'
);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $auth_data);
curl_setopt($curl, CURLOPT_URL, 'https://api-site.com/oauth/token');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$result = curl_exec($curl);
if(!$result){die("Connection Failure");}
curl_close($curl);
echo $result;

This will return an auth-token for me. With this auth token, I can start making normal API calls like POST and GET. However.. My example API only keeps my auth-token alive for 2 weeks AND will only allow 3 auth-tokens at a time. So for each call I make, I need to regenerate this. This is why I’m using JS as example, so we can easily quickly generate the AUTH token before our own call. For this, I have a separate JS function to post to our own api/auth.php: JS

const apiAuth = async () => {
  try{
    const response  = await fetch('https://my-site.com/api/auth.php');
    if(response.ok){
      return response.json();
    }
    throw new Error(`apiAuth_response: ${response}`);
  }catch(error){
    console.error(`apiAuth: ${error}`);
  }
}

This is the JS-script and the PHP-script I’m using to generate an auth-token for my API. I’m using await to make sure our script only continuous when we do have received the Auth token. If we don’t await this token, it’s possible the rest of our script will already try to make the API call without the utoken, and will return errors.

How to use our Auth-token?

Ok good, now we have an auth-token for our app… How do we use this?

cURL GET request (with Authentication)

In most cases (I think) you need to add your auth-token to the url you’re using to make a valid API call. Again, you should be able to find this in the documentation of the API your using. In my example, if I want to make an API call, my link should look like this: api/get_all_reviews.php

https://api-site.com/v1/apps/' . $app_key . '/reviews?utoken=' . $utoken;

We do know our $app_key and we just generated our $utoken. So our .php file to make the GET-call would look like this: ($_POST[‘auth_token’] will be our received utoken from our previous function.

if(isset($_POST['access_token'])){	
	$app_key  = 'XBnKaywRCrj05m-XXX-v6DXuZ3FFkUgiw45';
	$utoken = $_POST['access_token'];
	$url = 'https://api-site.com/v1/apps/' . $app_key . '/reviews?utoken=' . $utoken;
	
	$curl = curl_init();
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
   $result = curl_exec($curl);
   if(!$result){die("Connection Failure");}
   curl_close($curl);
   echo $result;
}

This will return all our product-reviews in the example I picked for this tutorial. Now we still need to target this GET php file with our JS and don’t forget to generate our utoken first! JS

const getAllReviews = async () => {
  const auth = await apiAuth();
  const data = {
    access_token: auth.access_token,
    token_type: auth.token_type,
  }
  try{
    $.post({
      type: 'POST',
      url: 'http://my-site.com/api/get_all_reviews.php',
      data: data
    })
    .success(res => {
      const data = JSON.parse(res);
      const reviews = data.reviews;
      displayAllReviews(reviews, $('.review-list'));
    });
  }catch(error){
    console.error(`getAllReviews: ${error}`);
  }
}

As you can see we await the Auth function again, before we continue with our original API call. We post the received auth.access_token together with our form data to our GET php script. The displayAllReviews() is a random function, that I am passing our received data to. So here you can call your own functions, depending on what you want to do with this data.

cURL POST request (with Authentication)

Same for POST as with GET, we need to add our utoken (Auth-token) to the url. Here is an example of my POST link to the API, with my utoken: api/post_review.php

if(isset($_POST['success'])){	
	$p_url = 'https://product-link.com';
	$email = $_POST['email'];
	
	$post_array = array(
		'appkey' => 'XBnKaywRCrj05m-XXX-v6DXuZ3FFkUgiw45',
		'domain' => 'https://api-site.com',
		'product_url' => $p_url,
		'email' => $email,
		'review_content' => $_POST['message'],
		'review_title' => $_POST['title'],
		'review_score' => $_POST['star_rating_value']
	);
	postReview($post_array);
}else{
	$response = array(
		'response' 	=> 'error',
		'message'	=> 'POST is required to use this function'
	);
}
function postReview($post_array){
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_POST, 1);
	curl_setopt($curl, CURLOPT_POSTFIELDS, $post_array);
	curl_setopt($curl, CURLOPT_URL, 'https://api-site.com/v1/reviews');
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
	
	$result = curl_exec($curl);
	if(!$result){die("Connection Failure");}
	curl_close($curl);
	echo $result;
}

To make a POST, I first gather all the information I need to make the post. (like user-email and the product URL I want to post a review for). When I have all the data, I call the postReview function, that will make the POST API call. We need to gather all this data up-front, otherwise we are not allowed to make our API call. As our POST request doesn’t require a utoken variable.

Now the JS script I used for this: JS

function postSiteReview(data, form){
  $.ajax({
    url: 'https://my-site.com/api/post_review.php',
    type: 'post',
    data: data,
    success: function(result){
      let res = JSON.parse(result);
      let message = '';
      if(res.code === 200){
        form.find('.success-message').fadeIn();
      }else{
        if(res.response === 'error'){
          message = res.message;
        }
        if(res.status && res.status.code === 500){
          message = res.status.message;
        }
        $('p.error-msg').text(`Uh ooh.. ${message}`);
      }
    },
    error: function(err){
      console.log('$.ajax error: ' + err);
    }
  });
}

No Access-Control-Allow-Origin header is present – (CORS)

If you’re making JS calls to your own php-files, but your files are on a different server, please at following line at the top of each .php file you’re using:

header("Access-Control-Allow-Origin: https://my-site.com");

This should fix the access-control error you’re seeing in the js-console.

I really hope this part is well-explained as well. If not, please feel free to ask in the comments. (I can not guarantee you will get a response).

Let me know if it works for you.
Happy coding!

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *