Get API response URL param using Guzzle HTTP request in Guzzle 7 - php

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');

Related

Getting API Response using Guzzle in Laravel

I am trying to get a response from the Metals API but keep getting 404 errors even though I can get the API using the URL.
public function valueFromApi(){
$accesskey = "123456";
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://metals-api.com/api/latest', [
'form_params' => [
'access_key' => $accesskey,
'base' => 'GBP',
'symbols' => 'XAU',]
]);
dd($response);
}
If I try and access the URL directly through a browser this works:
https://metals-api.com/api/latest?access_key=123456&base=GBP&symbols=XAU
I must have misunderstood the way the parameters are working. Any advice is appreciated.
Form params is not the same as query parameters. Therefor you need to set the parameters as query. If you are accessing this in the browser, i would not expect it to be a POST but a GET.
$response = $client->request('GET', 'https://metals-api.com/api/latest', [
RequestOptions::QUERY => [
'access_key' => $accesskey,
'base' => 'GBP',
'symbols' => 'XAU',
]
]);
I am using the RequestOptions, this is syntaxic sugar for the hardcoded string options, the same as 'query'.
As specified in their docs, you need to define the constant
define("form_params", GuzzleHttp\RequestOptions::FORM_PARAMS );
Then you can use your code
$response = $client->request('POST', 'https://metals-api.com/api/latest', [
'form_params' => [
'access_key' => $accesskey,
'base' => 'GBP',
'symbols' => 'XAU',]
]);

Passing client certificates through Curl request using Guzzle

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']

Shopify Trying to create a script tag in shopify but returns an error

I am trying to build an app in shopify, so uing their API,
as shown here
But while I am requesting a POST request on that URL i.e.
https://demo-store.myshopify.com/admin/script_tags.json
It is returning an error with HTTP status code 400 (Bad Request)
{"errors":{"script_tag":"expected String to be a Hash"}}
Sample code
$access_token = "my-access-token";
$client = new \GuzzleHttp\Client();
try {
$response = $client->request($type, $url,[
'headers' => ['X-Shopify-Access-Token' => $access_token],
'form_params' => ['script_tag'=> \GuzzleHttp\json_encode(["event" => "onload", "src" => "https://app.dev/app.js"])],
]);
$result = json_decode($response->getBody()->getContents(), true);
var_dump($response, $result);
} catch (\Exception $ex) {
var_dump($ex);
}
When making POST or PUT requests to Shopify's API you will usually want a Content-Type: application/json header. Version 6 of Guzzle has a json option that adds the header automatically.
Here's an example of what that could look like when creating a script tag:
$client = new \GuzzleHttp\Client();
$script_tag = [
'script_tag' => [
'src' => 'https://sdks.shopifycdn.com/js-buy-sdk/v0/latest/shopify-buy.umd.polyfilled.min.js',
'event' => 'onload'
]
];
$response = $client->request('POST', 'https://45345345345.myshopify.com/admin/script_tags.json', [
'json' => $script_tag,
'headers' => ['X-Shopify-Access-Token' => $access_token]
]);

Returning GuzzleHttp response object causes ERR_INVALID_CHUNKED_ENCODING in browser

I'm using guzzle 6 in laravel 5 to send a post request but I'm getting ERR_INVALID_CHUNKED_ENCODING when I try to access the request() in the method that handles the post request.
Here's my code:
Routes.php
Route::get('/guzzle', [
'as' => 'guzzle-test',
'uses' => 'TestController#getTest'
]);
Route::post('/guzzle', [
'as' => 'guzzle-post-test',
'uses' => 'TestController#postTest'
]);
TestController.php
public function getTest()
{
$client = new Client();
$data = [
'hey' => 'ho'
];
$request = $client->post(route('guzzle-post-test'), [
'content-type' => 'application/json'
], json_encode($data));
return $request;
}
public function postTest()
{
dd(getTest());
}
I getting to the post request handler since I've tried to diedump a string and it gets there, but if i call the request() I get that error. For what I've researched It may have something to with the content length, but after reading guzzle's docs and some stuff around the web I could find how to get and pass the content length appropriately in the request. Any help would be very appreciated!
First off, here's some test code which you should be able to adapt for your purposes (also see form_params in the docs for GuzzleHttp):
public function validateRecaptcha()
{
$client = new Client;
$response = $client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', [
'form_params' => [
'secret' => env('RECAPTCHA_SECRET'),
'response' => Request::input('g-recaptcha-response'),
'remoteip' => Request::ip()
]
]);
return $response;
}
I just ran into the same issue and found that trying to return the response object in Laravel gave me ERR_INVALID_CHUNKED_ENCODING. Whereas, doing a dd() on the response itself showed me what I was actually wanting to see:
public function validateRecaptcha()
{
$client = new Client;
$response = $client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', [
'form_params' => [
'secret' => env('RECAPTCHA_SECRET'),
'response' => Request::input('g-recaptcha-response'),
'remoteip' => Request::ip()
]
]);
dd($response);
}
Unfortunately, without doing further research, I'm unable to explain why ERR_INVALID_CHUNKED_ENCODING keeps coming up when I try to return the client library's objects to the browser, but my initial inclination is that it's a data type issue.
As far as your question goes, you're not actually trying to get back the "request" but rather the response. According to http://docs.guzzlephp.org/en/latest/quickstart.html#using-responses, if you want to get the API response contained in the response object (or at least in my case, I did), you'll want to use the getBody() method:
public function validateRecaptcha()
{
$client = new Client;
$response = $client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', [
'form_params' => [
'secret' => env('RECAPTCHA_SECRET'),
'response' => Request::input('g-recaptcha-response'),
'remoteip' => Request::ip()
]
]);
return $response->getBody();
}
And then of course, if you expect it to be a JSON response (i.e. REST), then simply pass it to json_decode() to get your associative array back.
public function validateRecaptcha()
{
$client = new Client;
$response = $client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', [
'form_params' => [
'secret' => env('RECAPTCHA_SECRET'),
'response' => Request::input('g-recaptcha-response'),
'remoteip' => Request::ip()
]
]);
return json_decode($response->getBody(), true); // true = assoc. array
}
Hope that helps!

How to get past login screen on Guzzle call

I have to send information to an external website using cURL. I set up Guzzle on my Laravel application. I have the basics set up, but according to the documentation of the website, there is an action that's required for the username and password. How can I pass the 'action' along with the credentials needed to log in and get access?
The website states:
curl [-k] –dump-header <header_file> -F “action=login” -F “username=<username>” -F “password=<password>” https://<website_URL>
My controller:
$client = new \GuzzleHttp\Client();
$response = $client->get('http://website.com/page/login/', array(
'auth' => array('username', 'password')
));
$xml = $response;
echo $xml;
The website will load on the echo, but it will only pull up the login screen. I need those credentials to bypass the login screen (with a successful login) to get to the portion of information I need for cURL.
curl -F submits a POST request instead of a GET request. So you'll need to modify your code accordingly, something like
$client = new \GuzzleHttp\Client();
$response = $client->post('http://website.com/page/login/', [
'body' => [
'username' => $username,
'password' => $password,
'action' => 'login'
],
'cookies' => true
]
);
$xml = $response;
echo $xml;
See http://guzzle.readthedocs.org/en/latest/quickstart.html#post-requests, http://curl.haxx.se/docs/manpage.html#-F
Edit:
Just add ['cookies' => true] to requests in order to use the auth cookie associated with this GuzzleHttp\Client(). http://guzzle.readthedocs.org/en/latest/clients.html#cookies
$response2 = $client->get('http://website.com/otherpage/', ['cookies' => true]);
I was having trouble getting #JeremiahWinsley's answer to work on newer version of Guzzle so I've updated their code to work as of Guzzle 5.x.
Three major changes are required
Using form_params instead of body to prevent the error "Passing in the "body" request option as an array to send a POST request has been deprecated."
Changing the cookies to use the CookieJar object
Use ->getBody()->getContents() to get the body of the request
Here is the updated code:
$client = new \GuzzleHttp\Client();
$cookieJar = new \GuzzleHttp\Cookie\CookieJar();
$response = $client->post('http://website.com/page/login/', [
'form_params' => [
'username' => $username,
'password' => $password,
'action' => 'login'
],
'cookies' => $cookieJar
]
);
$xml = $response->getBody()->getContents();
echo $xml;
And to continue using cookies in future requests, pass in the cookieJar to the request:
$response2 = $client->get('http://website.com/otherpage/', ['cookies' => $cookieJar]);
I was having trouble getting #JeremiahWinsley's and #Samsquanch's answer to work on newer version of Guzzle. So I've updated the code to work as of Guzzle 6.x.
Guzzle 6.x. documents: http://docs.guzzlephp.org/en/stable/index.html
Here is the updated code:
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
try {
$client = new Client();
$cookieJar = new CookieJar();
$response = $client->request('POST', 'http://website.com/page/login/', [
'form_params' => [
'username' => 'test#example.com',
'password' => '123456'
],
'cookies' => $cookieJar
]);
$response2 = $client->request('GET', 'http://website.com/otherpage/', [
'cookies' => $cookieJar
]);
if ($response2->getStatusCode() == 200) {
return $response2->getBody()->getContents();
} else {
return "Oops!";
}
} catch (\Exception $exception) {
return 'Caught exception: ', $exception->getMessage();
}

Categories