PHP Guzzle Sending 2 requests on same time - php

I'm trying to make 2 api calls at the same time, the first gets a token and the second brings the user data.
The problem is that when i pass the token on the second api call it gives me a session expired.
$client = new Client([
'base_uri' => 'https://portaldoagente.com.br/WCF/wcfTravellink/Loja.svc/',
'headers' => [
'Content-Type' => 'application/json'
]
]);
First call:
$response = $client->post('Autenticar',
['body' => json_encode(
[
'login' => 'example',
'senha' => 'example'
]
)],
);
$body = $response->getBody()->getContents();
$responseXml = simplexml_load_string($body);
$token = $responseXml->children;
$response = $client->post('ConsultarCliente',
['body' => json_encode(
[
'token'=> $token,
'ClienteLogin' => [
'Login' => 'example',
'Senha' => 'example'
]
]
)]
);
$Consulta = $response->getBody()->getContents();
The token needed to stay in the session so it would not expire?
When I try this in postman it works fine, first I make a call to the first method to get the token, then I make another call to the second method passing the token.

Related

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

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

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

Retrieve POST data sent with Guzzle (6.3) from Laravel

I am posting some data from my laravel app to another plain PHP page I have on my local server. The status code returned by Guzzle says it was successful but I am unable to access it. How can I do this?
I've tried using the Post method to retrieve value but no luck
Guzzle Function:
$client = new Client();
$response = $client->request('POST', 'http://localhost/testApp/guzTest.php',
[
'form_params' => [
'amnt' => 75
],
'allow_redirects' => true
]);
echo $response->getStatusCode();
Page Receiving POST DATA:
<?php
if (!empty($_POST['amnt'])) {
echo $_POST['amnt'];
}else
echo 'not found';
?>
I expect to be able to access the amount posted via post method but nothing is yielded.
Try somthing like that .
$client = new Client();
$response = $client->request('POST', 'http://localhost/testApp/guzTest.php',
[
'form_params' => [
'amnt' => 75
],
'allow_redirects' => true
]);
$contents = $response->getBody()->getContents();
$contents = json_decode($contents,true);
return ($contents);
On page Receiving POST DATA:
Response should be like this
return response()->json([
'status' => 'SUCCESS',
'code' => '200',
], 200);

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!

Can you include raw JSON in Guzzle POST Body?

This should be soo simple but I have spent hours searching for the answer and am truly stuck. I am building a basic Laravel application and am using Guzzle to replace the CURL request I am making at the moment. All the CURL functions utilise raw JSON variables in the body.
I am trying to create a working Guzzle client but the server is respsonding with 'invalid request' and I am just wondering if something fishy is going on with the JSON I am posting. I am starting to wonder if you can not use raw JSON in the Guzzle POST request body? I know the headers are working as I am receiving a valid response from the server and I know the JSON is valid as it is currently working in a CURL request. So I am stuck :-(
Any help would be sooo greatly appreciated.
$headers = array(
'NETOAPI_KEY' => env('NETO_API_KEY'),
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'NETOAPI_ACTION' => 'GetOrder'
);
// JSON Data for API post
$GetOrder = '{
"Filter": {
"OrderID": "N10139",
"OutputSelector": [
"OrderStatus"
]
}
}';
$client = new client();
$res = $client->post(env('NETO_API_URL'), [ 'headers' => $headers ], [ 'body' => $GetOrder ]);
return $res->getBody();
You can send a regular array as JSON via the 'json' request option; this will also automatically set the right headers:
$headers = [
'NETOAPI_KEY' => env('NETO_API_KEY'),
'Accept' => 'application/json',
'NETOAPI_ACTION' => 'GetOrder'
];
$GetOrder = [
'Filter' => [
'OrderID' => 'N10139',
'OutputSelector' => ['OrderStatus'],
],
];
$client = new client();
$res = $client->post(env('NETO_API_URL'), [
'headers' => $headers,
'json' => $GetOrder,
]);
Note that Guzzle applies json_encode() without any options behind the scenes; if you need any customisation, you're advised to do some of the work yourself
$res = $client->post(env('NETO_API_URL'), [
'headers' => $headers + ['Content-Type' => 'application/json'],
'body' => json_encode($getOrders, ...),
]);
Guzzle 7 Here
The below worked for me with raw json input
$data = array(
'customer' => '89090',
'username' => 'app',
'password' => 'pwd'
);
$url = "http://someendpoint/API/Login";
$client = new \GuzzleHttp\Client();
$response = $client->post($url, [
'headers' => ['Content-Type' => 'application/json', 'Accept' => 'application/json'],
'body' => json_encode($data)
]);
print_r(json_decode($response->getBody(), true));
For some reasons until I used the json_decode on the response, the output wasn't formatted.
You probably need to set the body mime type. This can be done easily using the setBody() method.
$request = $client->post(env('NETO_API_URL'), ['headers' => $headers]);
$request->setBody($GetOrder, 'application/json');

Categories