10

I want to send POST request to https using \Drupal::httpClient(). But ended up with error like

GuzzleHttp\Exception\RequestException: cURL error 60: SSL certificate problem: self signed certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

Below is my code.

$post_fields['name'] = 'aa';
    $fields_string = json_encode($post_fields);    
    $response = \Drupal::httpClient()
           ->post("https://localhost/example/api/user-update?_format=json", [
         'auth' => ['admin', 'admin'],
         'body' => $fields_string,
    'http_errors' => FALSE,
         'headers' => [
           'Content-Type' => 'application/json',
    ],
       ]);
    dsm($response->getBody()->getContents());

How to send POST request with \Drupal::httpClient().

5 Answers 5

9

The error message should inform you what is going on. You are using a self-signed certificate locally. This probably won't be an issue on your production sites, but this is not really useful for local development.

Inspect the \Drupal::httpClient() static method you may discover that it uses the http_client_factory:fromOptions service. Use this directly allows you to pass options into Guzzle to allow requests to sites using self-signed certificates.

$clientFactory = \Drupal::service('http_client_factory');
$client = $clientFactory->fromOptions(['verify' => FALSE]);

Obviously this is not ideal. You should probably parameterize the URL that you are using instead of hard coding the URL. Then locally you can test without a self-signed cert or HTTPS. Or parameterize the options you pass into Guzzle so that verify => TRUE when you're on production. It is not recommended to set it to FALSE and this is a security risk.

10

We must pass the post values in http_client via form_params . Here down is one of my code to make OAuth2 authentication to another drupal 8 REST api being used simple_oauth module.

$response = \Drupal::httpClient()->post($base_url . '/oauth/token', [
      'verify' => true,
      'form_params' => ['grant_type'=> 'password',
                        'client_id' => 'CLIENT-ID',
                        'client_secret'=> 'CLIENT-SECRET',
                        'scope'=>'',
                        'username'=>'admin',
                        'password'=>'admin',],
        'headers' => [
          'Content-type' => 'application/x-www-form-urlencoded',
        ],
    ])->getBody()->getContents();
1
  • If anyone is having any problems with any code in the answers, you need to change "form_params" to just "json", that may work for you :)
    – DarkteK
    Oct 26, 2022 at 18:42
1

$client = $clientFactory->fromOptions(['verify' => FALSE]); make me have an error.

I tried this line above, which is working :

$response = $client->request($methode, $url->toString(), ['form_params' => $options, 'verify' => false]);
0

You might get some idea from this doc https://www.drupal.org/docs/8/core/modules/rest/3-post-for-creating-content-entities

0

I tried the various answers above, none did quite work. As it happens there was, in our case, a simpler solution. We have several environments identified via $settings['environment'] in settings.php. One of those, "local", needs to work with self-signed certs. To avoid Guzzle/curl from complaining we do:

if ($environment == 'local') $params['verify'] = FALSE; // $params of course holds other needed bits for the call to happen...

$response = json_decode(Drupal::httpClient()
      ->post($target_url, $params)
      ->getBody()
      ->getContents());

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.