3

I have the following PHP curl code to generate a security token within an Application. When I run this code it works perfect.

    $ch = curl_init();
    
    curl_setopt($ch, CURLOPT_URL, 'https://host.com/api/v1/auth/keys');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, "{}");
    curl_setopt($ch, CURLOPT_USERPWD, 'admin' . ':' . 'password');
    
    $headers = array();
    $headers[] = 'Content-Type: application/json';
    $headers[] = 'Accept: application/json';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    
    $result = curl_exec($ch);
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }
    curl_close($ch);

But at the moment I need a Guzzle version of this Curl script and that's where this issue begins.

I found different ways to handle the Authentication within Guzzle but so far nothing works.

This is what I came up with.

       use GuzzleHttp\Client;
        
        include "../vendor/autoload.php";
        
        try{
        
          $client = new Client(['base_uri' => 'https://host.com/api/v1/']);
          
          $client->request('POST', 'auth/keys',[
              'config' => [
                'curl' => [
                  // CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
                    CURLOPT_USERPWD  => 'admin:password'
                ]
              ],
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Accept'       => 'application/json',
                ]
                ]);
        
            print_r($client->getBody()->getContents());
            
          }catch (Exception $e) {
            print_r([
                "status" => false,
                "message" => $e->getMessage()
            ]);
        }

Instead of returning a security token, I get an error message "401 Unauthorized` response" - which means no correct authentication received.

What exactly am I doing wrong?

Thank you in advance.

Rob
  • 6,819
  • 17
  • 71
  • 131
Riccoh
  • 359
  • 1
  • 4
  • 19
  • I don't see the path `auth/keys` in the **curl** version of your code. Shouldn't your path just be `/` ? – Andrea Olivato Jul 19 '21 at 16:17
  • Also usually you should use `'auth' => [ 'username', 'password' ]` for basic auth – Andrea Olivato Jul 19 '21 at 16:17
  • Does this answer your question? [How do I do HTTP basic authentication using Guzzle?](https://stackoverflow.com/questions/30970736/how-do-i-do-http-basic-authentication-using-guzzle) – Andrea Olivato Jul 19 '21 at 16:18
  • I already tried the solution in the link and the basic auth. Both dont work unfortunately. Somehow CURLOPT_USERPWD doesnt play nice with Guzzle. – Riccoh Jul 19 '21 at 17:25
  • https://stackoverflow.com/search?q=CURLOPT_USERPWD, have you checked those questions and evaluated if any of their answers solve your problem? That said, I get 404 when posting to that URL. Did you perhaps want to use `example.com`, which is explicitly designated for placeholder URLs in examples? – Ulrich Eckhardt Jul 19 '21 at 18:35
  • Yes of course, but I found the issue. Its seems that the API call requires a body post even if its empty.. But unfortunately they didnt documented this :( Thank you all for your time and effort much appreciated. – Riccoh Jul 19 '21 at 18:45

1 Answers1

2

I believe you are not well aware of how to use curl options within guzzle Only use curl as request option no need to use config.(See docs)

<?php
require "../vendor/autoload.php";

use GuzzleHttp\Client;
    
    try{
    
      $client = new Client(['base_uri' => 'https://host.com/api/v1/']);
      
      $guzzleResponse = $client->request('POST', 'auth/keys', [
                'curl' => [
                  CURLOPT_USERPWD  => 'admin:password'
                ],
              
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Accept'       => 'application/json',
                ]
            ]);
    
        print_r($guzzleResponse->getBody()->getContents());
        
    } catch (GuzzleHttp\Exception\RequestException $e) {
        print_r([
            "status" => false,
            "message" => $e->getMessage(),
        ]);// you can use logs here like monolog library
    } catch(Exception $e){
        print_r([
            "status" => false,
            "message" => $e->getMessage(),
        ]);
    }

method 2

Refering to this answer, I believe you can also use Basic Auth http header.

$encodedAuth = base64_encode( $usename.":".$passwd);

// ... other same as above

 $guzzleResponse = $client->request('POST', 'auth/keys', [
                'headers' => [
                    'Authorization' => 'Bearer '. $encodedAuth,
                    'Content-Type' => 'application/json',
                    'Accept'       => 'application/json',
                ]
            ]);
// ... other same as above

bhucho
  • 3,903
  • 3
  • 16
  • 34