2014-09-18 11 views
9

Tôi đang sử dụng Guzzle v3.9.2 với cả php 5.3 và php 5.5.Di chuyển khách hàng Curl ssl sang Guzzle

Tôi đã mã curl làm việc sau đó sử dụng một chứng chỉ SSL client:

$url = "https://example.com/"; 
$cert_file = '/path/to/certificate.pem'; 

$ch = curl_init(); 
$options = array(
    CURLOPT_RETURNTRANSFER => true, 
    CURLOPT_FOLLOWLOCATION => true, 
    CURLOPT_URL => $url , 
    CURLOPT_SSLCERT => $cert_file , 
); 

curl_setopt_array($ch , $options); 
$output = curl_exec($ch); 

if (!$output) { 
    echo "Curl Error : " . curl_error($ch); 
} 
else { 
    echo htmlentities($output); 
} 

Tôi đã cố gắng để di chuyển nó đến tật ham ăn:

require '/var/www/vendor/autoload.php'; 
use Guzzle\Http\Client; 
$client = new Client(); 
$request = $client->get($url, array('cert' => $cert_file)); 
$response = $client->send($request); 
echo $response . PHP_EOL; 
print 'HI' . PHP_EOL; 

Khi tôi chạy nó sử dụng curl tôi nhận được một 200 phản hồi. Khi tôi sử dụng hay uống rượu tôi nhận được một 403.

+1

'tùy chọn cert' chỉ làm việc với chứng chỉ khách hàng. Nếu bạn đang sử dụng chứng chỉ riêng thì curl sẽ cho bạn không thể đặt lỗi tệp khóa riêng tư. Xin vui lòng tham khảo câu trả lời của tôi dưới đây –

Trả lời

13

thử như thế này:

$client = new Client(); 
$response = $client->get($url, array(), array('cert' => $cert_file)); 

và để kiểm tra thêm dòng này:

$this->assertEquals($cert_file, $request->getCurlOptions()->get(CURLOPT_SSLCERT)); 

hoặc sử dụng này:

$client = new Client(); 
$request = $client->createRequest('GET', $url); 
$request->getCurlOptions()->set(CURLOPT_SSLCERT, $cert_file); 
$response = $client->send($request); 

nếu bạn sử dụng chứng chỉ tự ký được đặt tùy chọn này:

$request->getCurlOptions()->set(CURLOPT_SSL_VERIFYHOST, false); 
$request->getCurlOptions()->set(CURLOPT_SSL_VERIFYPEER, false); 

bộ dòng này trước khi gửi yêu cầu:

$request = $client->get(....) 
. 
. 
. 
$request->setResponse(new Response(200), true); 
$request->send(); 

kiểm tra url của bạn và nhập nó compelete như thế này:

$url = 'https://example.com/index.php'; 

và bạn có thể thêm tùy chọn mặc định như mã curl của bạn:

$request->getCurlOptions()->set(CURLOPT_RETURNTRANSFER , true); 
$request->getCurlOptions()->set(CURLOPT_FOLLOWLOCATION , true); 
+0

Vâng, tin tốt và xấu. Các công cụ assertEquals thực sự hiển thị cùng một giá trị. Nhưng ... bằng cách nào đó nó vẫn không hoạt động. Có thêm ý tưởng nào về cách gỡ lỗi không? – greggles

+1

trước khi gửi yêu cầu sử dụng var_dump ($ request-> getCurlOptions()); và xem các phần mở đầu được tạo ra –

+0

Điều này khiến tôi trả lời và tôi tin rằng câu trả lời chính xác nhất là chính xác, vì vậy tôi đã chấp nhận câu trả lời và trao tặng tiền thưởng. Vấn đề cuối cùng của tôi wsa rằng tôi đã nhận được một 403 về thực tế là danh sách thư mục đã bị từ chối (gợi ý về index.php làm cho tôi suy nghĩ về điều đó). Tôi đã bắt được ngoại lệ 403 từ Guzzle và in phần thân yêu cầu để biết đó là lỗi "danh sách thư mục bị từ chối" thay vì lỗi chứng chỉ. Cảm ơn! – greggles

1
If you are using private key then you have to use ssl_key option it will not 
work with cert.You can use **cert** options only with client certificate. 

Lỗi này xảy ra vì ba lý do.

  1. Đường dẫn chứng chỉ chính xác không được cung cấp. Do đó không thể đọc & chuyển thông tin chứng chỉ đến máy chủ.
  2. Máy chủ không thể xác thực yêu cầu do chứng chỉ không hợp lệ.
  3. Php curl không thể đọc tệp chứng chỉ do vấn đề về chủ sở hữu/quyền của tệp.

Làm thế nào tật ham ăn bộ ssl đường curl:

  • tật ham ăn sử dụng CURLOPT_CAINFO cho file & CURLOPT_CAPATH cho nhiều chứng chỉ trong thư mục
  • đường dẫn chứng chỉ mặc định là vendor/Http/Resources/cacert.pem.
  • Nếu bạn không sử dụng phar trong require_once thì bạn có thể thay thế tệp chứng chỉ hiện tại bằng chứng chỉ mới của mình vì nó khởi tạo SSL theo mọi yêu cầu. Điều này sẽ làm việc mà không thay đổi mã.
  • Sử dụng gút ssl.certificate_authority thông số để đặt chứng nhận ssl curl.Nó hỗ trợ các giá trị như sai, đúng hay đường dẫn tập tin
  • Bạn có thể thiết lập các đường dẫn tập tin trong khi khởi tạo lớp như liệt kê dưới đây

    $cert_file = '/var/www/stack/25924147/cert/example.pem'; #Use absolute path as relative path will not work 
    $client = new Client(); 
    $client->setDefaultOption('verify',true); #pass it for self-signed certificate 
    $client->setSslVerification($cert_file,true,2); #Last Verify Option states default value is 2. When the verify value is 0, the connection succeeds regardless of the names in the certificate. Use that ability with caution!. When the verify value is 1, curl_easy_setopt will return an error 
    try{ 
        $request = $client->get($url); 
        $options = $request->getCurlOptions(); #used to check curl options is set properly. 
        var_dump($options); 
        $response = $client->send($request); 
        echo $response . PHP_EOL; 
        print 'HI' . PHP_EOL; 
    }catch(Guzzle\Http\Exception\CurlException $e){ 
        print_r($e->getResponse()); 
        echo "\n Curl Error \n"; 
    }catch(Guzzle\Http\Exception\ClientErrorResponseException $e){ 
        print_r($e->getResponse()); 
        echo "\n Response Error \n"; 
    }catch(Guzzle\Http\Exception\RequestException $e){ 
        print_r($e->getResponse()); 
        echo "\n REquest Error \n"; 
    } 
    

HOẶC Nếu bạn muốn vượt qua giấy chứng nhận trên tất cả các yêu cầu thử dưới đây đang

$cert_file = '/var/www/stack/25924147/cert/example.pem'; #Use absolute path as relative path will not work 
    $client = new Client(); 
    $request = $client->get('https://www.example.com', array(), array(

     'ssl_key' => array('/etc/pki/private_key.pem') 

) 


With Passoword - 
$request = $client->get('https://www.example.com', array(), array(

    'ssl_key' => array('/etc/pki/private_key.pem', 's3cr3tp455w0rd') 

) 

Đối tật ham ăn Http kiểm tra client Doc - The Guzzle HTTP client

2

Thứ nhất, vì điều này dẫn đến một số nhầm lẫn, có hai phiên bản của tật ham ăn sẵn trên Gihub:

  • Guzzle3 (phiên bản cũ, bạn đang sử dụng)
  • Guzzle (phiên bản mới, viết lại)

Ở đây có hai (thử nghiệm làm việc) ví dụ một cho mỗi phiên bản của tật ham ăn:

đối với các phiên bản gần đây của Guzzle (không phải là cái gọi là phiên bản cũ Guzzle3) nó nên là:

use GuzzleHttp\Client; 

$client = new Client(); 
$response = $client->get($url, array('cert' => $cert_file)); 

var_dump($response); 

Hãy chắc chắn rằng giấy chứng nhận của khách hàng được lưu trữ ở định dạng PEM. Nếu chứng chỉ được bảo vệ bằng mật khẩu, bạn sẽ cần phải chỉ định nó như sau:

$response = $client->get($url, 
    array('cert' => array($cert_file, 'password' => '****')); 

!! Lưu ý mã trên để cung cấp mật khẩu được mô tả trong sách hướng dẫn nhưng không hoạt động trong phiên bản gần đây.

Đối với phiên bản cũ Guzzle3 (bạn đang sử dụng)

use Guzzle\Http\Client; 

// Create a client and provide a base URL 
$client = new Client(); 

$request = $client->get($url, array(), array(
    'cert' => $cert_file 
)); 

// You must send a request in order for the transfer to occur 
$response = $request->send(); 

var_dump($response); 
+0

Cảm ơn lời khuyên về PEM. Curl có sử dụng một định dạng khác với guzzle cho chứng chỉ không? Lưu ý rằng tôi đang chạy mã này một mảnh sau khi khác và giá trị chính xác $ cert_file hoạt động tốt cho curl và không cho guzzle. Không có gì về $ url cũng như các thay đổi $ cert_file. – greggles

+0

Ngoài ra, nhận xét của bạn về -> get() gửi yêu cầu không phù hợp với tài liệu về guzzle cũng như kinh nghiệm của tôi. Bạn có thể chỉ ra một tham chiếu về điều đó không? – greggles

+0

Lấy ví dụ đầu tiên trên trang này: https://github.com/guzzle/guzzle/blob/master/docs/clients.rst .. Bạn đã thử mã của tôi chưa? (Tôi đã lười biếng để thiết lập một máy chủ xác thực dựa trên máy chủ thử nghiệm xác thực cho đến nay). – hek2mgl

Các vấn đề liên quan