I have the following curl command
sudo curl -E openyes.crt.pem --key openyes.key.pem https://sky.myapitutorial.in:444/app/live/get
which works fine. But when I am trying to do from Guzzle, its failing.
I am unable to pass the client certificates in the request.
This is what I tried
$headers = ['Content-Type' => 'application/json','X-Client-Id' => config('mykey') , 'X-Client-Secret' => config('mykey')];
$client = new client();
try {
$response = $client->post(
$endpoint
,
['json' => $content, 'headers' => $headers,['connect_timeout' => 650]],
[
'config' => [
'curl' => [
'CURLOPT_SSLKEY' => base_path().'/openyes.key.pem',
'CURLOPT_SSLCERT' => base_path().'/openyes.crt.pem',
'CURLOPT_VERBOSE' => true
],
]
],
['debug'=>true],
['http_errors' => false]
);
dd($response);
}
catch (GuzzleHttp\Exception\ClientException $e) {
$response = $e->getResponse();
throw $e;
}
I couldn't find any solution in Guzzle documentation.
Any idea why is this not working?
The error I am getting is
cURL error 35: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure (see http:\/\/curl.haxx.se\/libcurl\/c\/libcurl-errors.html)
You can use ssl_key and cert:
$response = $client->post(
$endpoint, [
'json' => $content,
'headers' => $headers,
'connect_timeout' => 650,
// add these
'cert' => '/path/to/openyes.crt.pem',
'ssl_key' => '/path/to/openyes.key.pem'
]
);
if they have a pass phrase, you can set them like this:
'cert' => ['/path/to/openyes.crt.pem', 'password'],
'ssl_key' => ['/path/to/openyes.key.pem', 'password']
Related
I searched online but couldn't find a proper solution. I am calling a Spring service with a POST request using Guzzle Client, The service in case of any errors provides the error message in its URL param like: http://localhost:8085/fedauth/null?errMessage=Mot%20de%20passe%20invalide%20pour%20l'utilisateur%20Karan%20Sharma.. How can I fetch this param errMessage using Guzzle. Below is my code with Slim in PHP.
$data = [
'userName' => base64_encode($userName),
'userPassword' => base64_encode($userPassword),
'institution' => $institution,
'redirectUrl' => $redirectUrl,
'callerUrl' => $callerUrl,
'clientId' => $clientId,
'encryptMode' => $encryptMode,
'moodleLandPage' => $moodleLandPage,
'login' => $login,
'isEncrypted' => true
];
try {
$apiResponse = $client->post( $_ENV['FEDAUTH_API_URL'], ['form_params'=> $data]);
} catch (Exception $exception) {
return $response->write(json_encode(['error' => $exception->getMessage(), "auth" => "0" ]));
}
I have tried using the getEffectiveUrl() method but its no longer supported in Guzzle 7
I guess you get the response as a redirect url? Your question is not clear in that point. In this case you can access it like this:
$apiResponse = $client->post( $_ENV['FEDAUTH_API_URL'], ['form_params'=> $data]);
echo $apiResponse->getEffectiveUrl();
like here: https://docs.guzzlephp.org/en/5.3/http-messages.html#responses
Actually found the answer. You need to add track redirects option as true and then use $response->getHeaderLine('X-Guzzle-Redirect-History'); like below
$client = new GuzzleHttp\Client(['headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded'], 'verify' => false, 'allow_redirects' => ['track_redirects' => true]]);
$apiResponse = $client->post( $_ENV['FEDAUTH_API_URL'], ['form_params'=> $data]);
echo $apiResponse->getHeaderLine('X-Guzzle-Redirect-History');
First of all: First question here in Stack Overflow, quite an honor! :D
How do i convert the following curl into Guzzle?
curl -u USER_KEY:USER_SECRET https://api.apiexample.com/example/oauth/oauth?grant_type=client_credentials
I tried the following, but i kept getting 403 - Forbidden error:
$res = $client->request('GET', 'https://api.apiexample.com/example/oauth/oauth',[
'auth' => ['USER_KEY', 'USER_SECRET'],
'header' => [
'Content-Type' => 'application/x-www-form-urlencoded'
],
'form_params' => [
'grant_type' => 'client_credentials'
]
]);
What could be wrong with my code?
Edit: Forgot one thing: This request returns a token that lasts for 30 minutes. Any tip to run this function only when the token is about to expire?
I would recommend maybe reformatting your request by putting your constant values in the Client object declaration and also wrapping the request in a try-catch block. The try-catch block provides the added benefit that it will help you debug the response. Feel free to alter the catch statement as you wish.
$client = new Client([
'base_uri' => 'https://api.apiexample.com/example/',
'auth' => [
'USER_KEY',
'USER_SECRET'
]
]);
try {
$response = $client->request( 'GET', 'oauth/oauth', [
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
],
'form_params' => [
'grant_type' => 'client_credentials'
]
]);
} catch (Exception $e) {
error_log($e->getCode());
error_log($e->getMessage());
error_log(print_r($e->getTrace(), true));
}
use GuzzleHttp\Client;
function insert_freshdesk_note($ticketId, $content, $attachments=null)
{
if(is_null($content)) {
return false;
}
$url = 'https://mydomain.freshdesk.com/api/v2/tickets/'.$ticketId.'/notes';
$method = 'POST';
$userName = config('freshdesk_api_key');
$password = 'password';
$data = (!empty($attachments)) ? [
"attachments[]" => $attachments,
"body" => $content,
"private" => false,
] : [
"body" => $content,
"private" => false,
];
$options = (!empty($attachments)) ? [
'json' => $data,
'auth' => [$userName, $password],
'headers' => ['content-type' => 'multipart/form-data']
] : [
'json' => $data,
'auth' => [$userName, $password]
];
$client = new Client();
try {
$response = $client->request($method, $url, $options);
return json_decode($response->getBody(), true);
} catch (Exception $e) {
Log::error($e);
}
}
Above code is working fine without attachments but when an attachment comes into the picture it's throwing the following error:-
GuzzleHttp\Exception\ClientException: Client error: `POST https://mydomain.freshdesk.com/api/v2/tickets/13033/notes` resulted in a `400 Bad Request` response:
{"description":"Validation failed","errors":[{"field":"{\"attachments","message":"Unexpected/invalid field in request","
I am working according to the documentation and I have hit a dead end as of this point. I tried other permutations and combinations but via those, I wasn't able to resolve this problem.
Can anyone please help me.
Here is the link of the documentation of freshdesk
And in $attachments[] = '#/path/to/xyz.ext' this particular is going.
The function call will go like this:-
insert_freshdesk_note($this->freshdesk_ticket_id, $noteText, $image->image_full_path);
In the above question, I was trying to achieve the addition of note using GuzzleHTTP Client, Laravel Framework, and PHP language. Here's the following source code by which it starts working.
use GuzzleHttp\Client;
function insert_freshdesk_note($ticketId, $content, $attachments=null)
{
if(is_null($content)) {
return false;
}
$url = 'https://mydomain.freshdesk.com/api/v2/tickets/'.$ticketId.'/notes';
$method = 'POST';
$userName = config('freshdesk_api_key');
$password = 'password';
$attachmentsFilePath = explode('/',$attachments);
$fileName = end($attachmentsFilePath);
$options = (!empty($attachments)) ? [
'multipart' => [
[
'name' => 'body',
'contents' => $content,
],
[
'name' => 'private',
'contents' => "false",
],
[
'name' => 'attachments[]',
'contents' => fopen($attachments, 'r'),
'filename' => $fileName,
],
],
'auth' => [$userName, $password],
] : [
'json' => [
"body" => $content,
"private" => false,
],
'auth' => [$userName, $password]
];
$client = new Client();
try {
$response = $client->request($method, $url, $options);
return json_decode($response->getBody(), true);
} catch (Exception $e) {
Log::error($e);
}
}
We have to send the data in multipart fashion in order to Freshdesk backend to understand that data is there, by writing multipart/form-type in the header won't help. If you look at documentation also with and without attachments below:-
Without Attachment:-
curl -v -u user#yourcompany.com:test -H "Content-Type: application/json" -X POST -d '{ "body":"Hi tom, Still Angry", "private":false, "notify_emails":["tom#yourcompany.com"] }' 'https://domain.freshdesk.com/api/v2/tickets/3/notes'
With Attachment:-
curl -v -u user#yourcompany.com:test -F "attachments[]=#/path/to/attachment1.ext" -F "body=Hi tom, Still Angry" -F "notify_emails[]=tom#yourcompany.com" -X POST 'https://domain.freshdesk.com/api/v2/tickets/20/notes'
The difference in the curl can be seen.
This was the missing piece that I overlooked.
I use Guzzle in my Laravel 5.8 project
I'm trying to make a GET to a URL (signed cert) serve on https
"https://172.1.1.1:443/accounts"
public static function get($url) {
// dd($url);
try {
$client = new Client();
$options = [
'http_errors' => true,
'connect_timeout' => 3.14,
'read_timeout' => 3.14,
'timeout' => 3.14,
'curl' => array(
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false
)
];
$headers = [
'headers' => [
'Keep-Alive' => 'timeout=300'
]
];
$result = $client->request('GET', $url, $headers, $options);
// dd($result);
} catch (ConnectException $e) {
//Logging::error($e);
return null;
}
return json_decode($result->getBody(), true);
}
I used these 2 flags already
CURLOPT_SSL_VERIFYHOST => false,
URLOPT_SSL_VERIFYPEER => false
I'm not sure why I kept getting,
the only sensible explanation (short of cosmic rays and ram errors) is that Client (whatever Client is) is either overriding your custom curl settings, or ignoring them. there should be no way to get that error with CURLOPT_SSL_VERIFYHOST & CURLOPT_SSL_VERIFYPEER disabled.
... btw if that is a Guzzle\Client, have you tried adding 'verify' => 'false' to $options ? that's supposedly the guzzle-way of disabling it, wouldn't surprise me if Guzzle is overriding your custom settings because of Guzzle's verify option not being disabled (it's enabled by default)
I'm agree with #hanshenrik, I tested it and it's the exact problem. By default the client you create have the following configuration:
$defaults = [
'allow_redirects' => RedirectMiddleware::$defaultSettings,
'http_errors' => true,
'decode_content' => true,
'verify' => true,
'cookies' => false
];
So you have to change it to:
public static function get($url) {
// dd($url);
try {
$client = new Client(['verify' => false]);
$options = [
'http_errors' => true,
'connect_timeout' => 3.14,
'read_timeout' => 3.14,
'timeout' => 3.14
)
];
$headers = [
'headers' => [
'Keep-Alive' => 'timeout=300'
]
];
$result = $client->request('GET', $url, $headers, $options);
// dd($result);
} catch (ConnectException $e) {
//Logging::error($e);
return null;
}
return json_decode($result->getBody(), true);
}
I'm trying to create a wrapper for a payment gateway api. I've chosen to use GuzzleHttp. Here is the basic code that I currently have. As the gateway expects input to be JSON formatted sent via HTTP POST, I tried two possible ways:
Using the json option and assigning a key-based array to it.
Explicitly setting content-type to application/json and sending a json formatted string via body.
Code:
$client = new Client([
'base_uri' => 'https://sandbox.gateway.com',
]);
$input = [
'merchant_id' => '12345-33445',
'security_key' => '**********',
'operation' => 'ping',
];
$clientHandler = $client->getConfig('handler');
$tapMiddleware = Middleware::tap(function ($request) {
foreach($request->getHeaders() as $h=>$v){
echo $h . ': ' . print_r($v) . PHP_EOL;
}
});
try {
$response = $client->post(
'/pg/auth',
[
'timeout' => 30,
'headers' => [
'Content-Type' => 'application/json',
'Cache-Control' => 'no-cache',
],
'body' => json_encode($input),
'debug' => true,
'handler' => $tapMiddleware($clientHandler)
]
);
print_r($response);
} catch(Exeption $e){
print_r($e);
}
Unfortunately, gateway got back with a 401 error although the credentials are correct. I suspect the way request is sent has an issue. I came to this conclusion as the headers printed from within the tap function are all arrays (especially content-type) instead of strings. Unlike what is described here http://guzzle.readthedocs.org/en/latest/request-options.html?highlight=request#json.
Array
(
[0] => GuzzleHttp/6.1.1 curl/7.43.0 PHP/5.5.29
)
User-Agent: 1
Array
(
[0] => sandbox.gateway.com
)
Host: 1
Array
(
[0] => application/json
)
Content-Type: 1
How about sending the request as suggested?
$client = new Client([
'base_uri' => 'https://sandbox.gateway.com',
]);
$client->request('POST', '/pg/auth', [
'timeout' => 30,
'debug' => true,
'json' => [
'merchant_id' => '12345-33445',
'security_key' => '**********',
'operation' => 'ping',
],
]);
For reference, see http://docs.guzzlephp.org/en/latest/request-options.html#json.