¿Cómo hago una solicitud usando la autenticación básica HTTP con PHP curl?

225

Estoy creando un cliente de servicio web REST en PHP y en este momento estoy usando curl para hacer solicitudes al servicio.

¿Cómo uso curl para hacer solicitudes autenticadas (http básica)? ¿Tengo que agregar los encabezados yo mismo?

blanco
fuente

Respuestas:

392

Tu quieres esto:

curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);  

Zend tiene un cliente REST y zend_http_client y estoy seguro de que PEAR tiene algún tipo de envoltorio. Pero es bastante fácil de hacer por su cuenta.

Entonces, toda la solicitud podría verse así:

$ch = curl_init($host);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml', $additionalHeaders));
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payloadName);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$return = curl_exec($ch);
curl_close($ch);
señor-sk
fuente
Esto funcionó mejor que configurar el usuario y la contraseña por separado
Kit Ramos
125

CURLOPT_USERPWDbásicamente envía la base64 de la user:passwordcadena con el encabezado http como a continuación:

Authorization: Basic dXNlcjpwYXNzd29yZA==

Además CURLOPT_USERPWD, también puede usar la HTTP-Requestopción de encabezado, como a continuación con otros encabezados:

$headers = array(
    'Content-Type:application/json',
    'Authorization: Basic '. base64_encode("user:password") // <---
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
Sabuj Hassan
fuente
Este método de pasar un encabezado de autenticación personalizado en lugar de usar CURLOPT_USERPWDfuncionó para mí.
aalaap
40

La forma más simple y nativa es usar CURL directamente.

Esto funciona para mi:

<?php
$login = 'login';
$password = 'password';
$url = 'http://your.url';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$login:$password");
$result = curl_exec($ch);
curl_close($ch);  
echo($result);
Fedir RYKHTIK
fuente
7

A diferencia de SOAP, REST no es un protocolo estandarizado, por lo que es un poco difícil tener un "Cliente REST". Sin embargo, dado que la mayoría de los servicios RESTful usan HTTP como su protocolo subyacente, debería poder usar cualquier biblioteca HTTP. Además de cURL, PHP tiene estos a través de PEAR:

HTTP_Request2

que reemplazó

HTTP_Request

Una muestra de cómo hacen HTTP Basic Auth

// This will set credentials for basic auth
$request = new HTTP_Request2('http://user:[email protected]/secret/');

También son compatibles con Digest Auth

// This will set credentials for Digest auth
$request->setAuth('user', 'password', HTTP_Request2::AUTH_DIGEST);
nategood
fuente
Por cliente REST quiero decir algo que abstrae algunos de los detalles de bajo nivel del uso de curl para http get, post, put, delete, etc., que es lo que estoy haciendo al construir mi propia clase php para hacer esto; Me pregunto si alguien ya ha hecho esto.
blanco el
1
Sí, entonces HTTP_Request_2 puede ser de su interés. Extrae muchos de los más feos de cUrl en PHP. Para configurar el método que utiliza, setMethod (HTTP_Request2 :: METHOD_ *). Con PUT y POSTs, para configurar el cuerpo de la solicitud, simplemente configureBody (<< su representación xml, json, etc. aquí >>). Autenticación descrita anteriormente. También tiene abstracciones para la respuesta HTTP (algo que realmente carece de cUrl).
nategood
6

Si el tipo de autorización es Autenticación básica y los datos publicados son json, haga lo siguiente

<?php

$data = array("username" => "test"); // data u want to post                                                                   
$data_string = json_encode($data);                                                                                   
 $api_key = "your_api_key";   
 $password = "xxxxxx";                                                                                                                 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "https://xxxxxxxxxxxxxxxxxxxxxxx");    
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");  
curl_setopt($ch, CURLOPT_POST, true);                                                                   
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);                                                                  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);     
curl_setopt($ch, CURLOPT_USERPWD, $api_key.':'.$password);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(   
    'Accept: application/json',
    'Content-Type: application/json')                                                           
);             

if(curl_exec($ch) === false)
{
    echo 'Curl error: ' . curl_error($ch);
}                                                                                                      
$errors = curl_error($ch);                                                                                                            
$result = curl_exec($ch);
$returnCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);  
echo $returnCode;
var_dump($errors);
print_r(json_decode($result, true));
Sunny Vashisht
fuente
4

Solo necesita especificar las opciones CURLOPT_HTTPAUTH y CURLOPT_USERPWD:

$curlHandler = curl_init();

$userName = 'postman';
$password = 'password';

curl_setopt_array($curlHandler, [
    CURLOPT_URL => 'https://postman-echo.com/basic-auth',
    CURLOPT_RETURNTRANSFER => true,

    CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
    CURLOPT_USERPWD => $userName . ':' . $password,
]);

$response = curl_exec($curlHandler);
curl_close($curlHandler);

O especifique el encabezado:

$curlSecondHandler = curl_init();

curl_setopt_array($curlSecondHandler, [
    CURLOPT_URL => 'https://postman-echo.com/basic-auth',
    CURLOPT_RETURNTRANSFER => true,

    CURLOPT_HTTPHEADER => [
        'Authorization: Basic ' . base64_encode($userName . ':' . $password)
    ],
]);

$response = curl_exec($curlSecondHandler);
curl_close($curlSecondHandler);

Ejemplo de Guzzle:

use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;

$userName = 'postman';
$password = 'password';

$httpClient = new Client();

$response = $httpClient->get(
    'https://postman-echo.com/basic-auth',
    [
        RequestOptions::AUTH => [$userName, $password]
    ]
);

print_r($response->getBody()->getContents());

Ver https://github.com/andriichuk/php-curl-cookbook#basic-auth

Serhii Andriichuk
fuente
3

El muy activo Guzzle de Michael Dowling es un buen camino a seguir. Además de la elegante interfaz, las llamadas asíncronas y el cumplimiento de PSR, hace que los encabezados de autenticación para las llamadas REST sean simples:

// Create a client with a base URL
$client = new GuzzleHttp\Client(['base_url' => 'http://myservices.io']);

// Send a request to http://myservices.io/status with basic authentication
$response = $client->get('/status', ['auth' => ['username', 'password']]);

Ver los documentos .

Jannie Theunissen
fuente
3

Para aquellos que no quieren usar curl:

//url
$url = 'some_url'; 

//Credentials
$client_id  = "";
$client_pass= ""; 

//HTTP options
$opts = array('http' =>
    array(
        'method'    => 'POST',
        'header'    => array ('Content-type: application/json', 'Authorization: Basic '.base64_encode("$client_id:$client_pass")),
        'content' => "some_content"
    )
);

//Do request
$context = stream_context_create($opts);
$json = file_get_contents($url, false, $context);

$result = json_decode($json, true);
if(json_last_error() != JSON_ERROR_NONE){
    return null;
}

print_r($result);
Wouter
fuente