I read from here : http://www.phplab.info/categories/laravel/consume-external-api-from-laravel-5-using-guzzle-http-client
I try like this :
...
use GuzzleHttp\Client as GuzzleHttpClient;
use GuzzleHttp\Exception\RequestException;
...
public function testApi()
{
try {
$client = new GuzzleHttpClient();
$apiRequest = $client->request('POST', 'https://myshop/api/auth/login', [
// 'query' => ['plain' => 'Ab1L853Z24N'],
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'auth' => ['test#gmail.com', '1234'], //If authentication required
// 'debug' => true //If needed to debug
]);
$content = json_decode($apiRequest->getBody()->getContents());
dd($content);
} catch (RequestException $re) {
//For handling exception
}
}
When executed, the result is null
How can I get the response?
I try in postman, it success get response
But I try use guzzle, it failed
Update :
I check on the postman, the result works
I try click button code on the postman
Then I select php curl and I copy it, the result like this :
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://myshop/api/auth/login",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\ntest#gmail.com\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n1234\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
"postman-token: 1122334455-abcd-edde-aabe-adaddddddddd"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
If it use curl php, the code like that
How can I get the response if it use guzzle?
I see at least one syntax mistake. The third argument of the request() method should look like this:
$requestContent = [
'headers' = [],
'json' = []
];
In your case it could be:
public function testApi()
{
$requestContent = [
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json'
],
'json' => [
'email' => 'test#gmail.com',
'password' => '1234',
// 'debug' => true
]
];
try {
$client = new GuzzleHttpClient();
$apiRequest = $client->request('POST', 'https://myshop/api/auth/login', $requestContent);
$response = json_decode($apiRequest->getBody());
dd($response);
} catch (RequestException $re) {
// For handling exception.
}
}
There are other parameters instead of json for your data, for example form_params. I suggest you take a look at the Guzzle documentation.
Related
In a PHP OAuth Implementation, there is a function as below:
/**
* Processes POST requests to /oauth/token.
*/
public function token(ServerRequestInterface $request) {
// Extract the grant type from the request body.
$body = $request->getParsedBody();
$grant_type_id = !empty($body['grant_type']) ? $body['grant_type'] : 'implicit';
/*.. CODE TRIMMED ..*/
catch (OAuthServerException $exception) {
watchdog_exception('simple_oauth', $exception);
$response = $exception->generateHttpResponse(new Response());
}
return $response;
}
I think its an instance of:
Psr\Http\Message\ServerRequestInterface;
I want to call this function, and pass the body params to this function from another function. Something as below:
public function call_token(){
//Something like this??
$request = new ServerRequestInterface();
$request->setUrl('https://some.url/oauth/token');
$request->setMethod("POST");
$request->setHeader(array(
'Content-Type' => 'application/x-www-form-urlencoded',
));
$request->addPostParameter(array(
'grant_type' => 'password',
'client_id' => '828472a8-f2c5-4e79-a158-ab041d3b313a',
'client_secret' => 'secret',
'username' => 'admin',
'password' => '123'
));
$response = $token($request);
}
I am not able to figure out how we can call this function.
This is the full source code where the token code is implemented. I am trying to call this function from another class.
Below is a working CURL request of how requests are made to this endpoint. I however want to emulate the request from within the application.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://some.url/oauth/token',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => 'grant_type=password&client_id=828472a8-f2c5-4e79-a158-ab041d3b313a&client_secret=secret&username=admin&password=123',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/x-www-form-urlencoded',
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Whenever I use Postman to make a soap post request, I get back the desired data. Using Guzzle, no data is returned. Im new to SOAP and using the resources online to go along.
I have omitted the variables for ease of read.
$xml = (
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:app="<ACTION-URL>">
<soapenv:Body>
<app:' . $functionName . '>
<request>'
. $requestBody .
'<authentication>
<username>'. $authObject->username .'</username>
<password>'. $authObject->password .'</password>
<user_id>'. $authObject->userId .'</user_id>
<dealer_id>'. $authObject->clientBranchId .'</dealer_id>
</authentication>
</request>
</app:' . $functionName . '>
</soapenv:Body>
</soapenv:Envelope>'
);
private function makeSOAPRequest($xml)
{
$client = new \GuzzleHttp\Client();
$options = [
'headers' => [
'Content-Type' => 'text/xml; charset=utf-8'
],
'body' => $xml,
'Authenticate' => [env('USERNAME'), env('PASSWORD')]
];
$url = env('ROSETTA_API');
$promise = $client->requestAsync('POST', $url, $options);
$response = $promise->wait();
$xml = simplexml_load_string($response->getBody(),'SimpleXMLElement',LIBXML_NOCDATA);
if ($xml) {
$json = json_encode($xml);
return json_decode($json, true);
}
return false;
}
Calling makeSOAPRequest(..), I get back false. Using the same xml data in Postman, data is returned. Is there anything I've missed in the request header?
Edit to use cURL
// Copied from Postman:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://<URL>",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $xml,
CURLOPT_HTTPHEADER => array(
"Cookie: PHPSESSID=6419f1d96025a4a2c4d454de33fc6820"
),
));
$response = curl_exec($curl);
curl_close($curl);
return $response; // xml data in string format.
cUrl does work but not Guzzle. How to return as json? When I use simplexml_load_string, it's empty.
Try to use below parameters in your curl:
CURLOPT_SSL_VERIFYPEER => 1
CURLOPT_POST => true
// IF NEEDED
CURLOPT_HTTPAUTH => CURLAUTH_ANY
// IF NEEDED
CURLOPT_USERPWD => $soapUser.":".$soapPassword)
For Checking Error After curl_exec and before curl_close
if( curl_errno($ch) ){
print_r(curl_error($curl));
}
In add these headers in your header if needed:
"accept" => "*/*",
// IF NEEDED
"accept-encoding" => "gzip, deflate"
Add your request code in try catch block:
try{
//request code
}
catch(Exception $e){
print_r($e->getCode());
print_r($e->getMessage());
}
I'm setting new fitur Login API in my website using cUrl.
When I run in Postman, is working (screnshoot 2). but when i run in my website using cUrl is not working and still loading. if i not set timeout, it will continue to load until infinite time like in screnshoot 1.
image 1 : when i run in my website
image 2 : when i run in Postman
This is my code
Login Controller for proses login from API/cUrl Request
public function login()
{
if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$user = Auth::user();
return response()->json(['result' => true, 'message' => "heyho" ], 200);
// $token = $user->createToken('nApp')->accessToken;
// return response()->json(['result' => true, 'message' => $token ], $this->successStatus);
} else {
return response()->json(['result'=> false, 'message' => 'Unauthorised'], 401);
}
}
This is my code cUrl Process/Request.
public function tes()
{
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_PORT => "8001",
CURLOPT_URL => "http://localhost:8001/api/login",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\email#gmail.com\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\bbbbb\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
"postman-token: 3546ebed-2016-df32-6d9d-91cdfd43066a"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
// return url('/')."/api/login";
}
Your request is "POST" then how you can see the result in web page
Only "GET" request only show the results on the web page
"GET" : In this case we can pass the parameter in the url
like : https//:localhost:8000/api/user/1
"POST" : In this case we pass the body in the request body so we need postman to pass the request body"
For more info you can check https://www.w3schools.com/tags/ref_httpmethods.asp
Context:
I've been working on figuring out how to make this work for a while, and I simply don't understand why Guzzle isn't working for this particular request. The same initialization and request structure works in some basic unit tests I have, but when it comes to API to API communication, Guzzle just is not cooperating.
Problem:
What I mean by that is, it's not including the headers I'm setting in the $headers array, and the request body is empty.
Desired result:
To confirm this is an issue with Guzzle, I've written out the request with typical cURL syntax, and the request goes through fine. I just need some guidance on how to make this work with Guzzle, as I like the abstraction Guzzle offers over verbose cURL requests.
Working cURL request:
$headers = array(
'Authorization: Bearer '.$sharedSecret,
'Content-Type: application/x-www-form-urlencoded',
'Accept: application/json',
'Content-Length: '.strlen($loginDetails),
);
$curlOptions = array(
CURLOPT_URL => API_URL.'member/SessionManager',
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => FALSE,
CURLOPT_HEADER => FALSE,
CURLOPT_FOLLOWLOCATION => FALSE,
CURLOPT_ENCODING => "",
CURLOPT_USERAGENT => "PORTAL",
CURLOPT_AUTOREFERER => TRUE,
CURLOPT_CONNECTTIMEOUT => 120,
CURLOPT_TIMEOUT => 120,
CURLOPT_MAXREDIRS => 10,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $loginDetails,
CURLOPT_SSL_VERIFYHOST => FALSE,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_VERBOSE => FALSE
);
try {
$ch = curl_init();
curl_setopt_array($ch,$curlOptions);
$content = curl_exec($ch);
$err = curl_errno($ch);
$errmsg = curl_error($ch);
$response = curl_getinfo($ch);
curl_close($ch);
if ($content === FALSE) {
throw new Exception(curl_error($ch), curl_errno($ch));
} else {
return true;
}
} catch(Exception $e) {
trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
}
The Guzzle client is initialized in a global file that creates a container which stores various objects we use throughout the application. I'm including it in case I missed something vital that isn't in Guzzle's documentation.
Guzzle initialization:
$container['client'] = function ($c) {
return new \GuzzleHttp\Client([
'base_uri' => API_URL,
'timeout' => 30.0,
'allow_redirects' => true,
'verify' => false,
'verbose' => true,
[
'headers' => [
'Authorization' => 'Bearer '.$sharedSecret,
]
],
]);
};
Non-working Guzzle Request:
$headers = array(
'Authorization' => 'Bearer '.$sharedSecret,
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept' => 'application/json',
'Content-Length'=> strlen($loginDetails),
);
try {
$response = $this->client->post('/api/member/SessionManager',
['debug' => true],
['headers' => $headers],
['body' => $loginDetails]
);
if($response) {
$this->handleResponse($response);
}
} catch (GuzzleHttp\Exception\ClientException $e) {
$response->getResponse();
$responseBodyAsString = $response->getBody()->getContents();
}
Whether I remove the headers array in the Guzzle initialization or not, it doesn't matter. The Authorization header is nowhere to be found in the request (confirmed with tcpdump, Wireshark, and receiving API error logging), and Guzzle's debug output shows no indication of my headers, nor my request body being anywhere in the request.
I'm stumped as to why this isn't working, and would very much like to understand. I can go the route of not using Guzzle, but would really prefer to due to brevity. Any input would be greatly appreciated.
In cURL request, the API URL being called is
API_URL.'member/SessionManager'
While in Guzzle request, the API URL being called has extra text "/api/"
(assuming API_URL is defined same in both cases)
new \GuzzleHttp\Client([
'base_uri' => API_URL,
...
$this->client->post('/api/member/SessionManager',
Appreciate that the question is old, but I thought I'd share my experience as I also struggled with this. The equivalent of:
CURLOPT_POSTFIELDS => $loginDetails,
in Guzzle is:
"query" => $loginDetails
In addition, I have found that if the base_uri does not end with a /, Guzzle will misunderstand it.
With all that in mind, your POST request should be as follows:
$response = $this->client->post('api/member/SessionManager', // Removed the first / as it's part of the base_uri now
['debug' => true],
['headers' => $headers],
['query' => $loginDetails] // Replaced "body" with "query"
);
I'm attempting to push a notification to a specific Android device using a heroku PHP server. I'm not having any luck in doing so, however.
I can push a notification through the firebase console just fine (i.e. the problem is not with my Android app).
Here is my code (which I got from How do I send a POST request with PHP?):
$url = 'https://fcm.googleapis.com/fcm/send';
$data = array('score' => '5x1', 'time' => '15:10');
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/json\r\n" .
"Authorization: key=MY_SERVER_KEY\r\n",
'method' => 'POST',
'data' => http_build_query($data),
'to' => 'MY_FCM'
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }
var_dump($result);
I feel like I'm doing something terribly basic wrong (like my JSON is not formatted correctly or something).
The firebase apis can be found here: https://firebase.google.com/docs/cloud-messaging/send-message
I've been working on this for a couple days now, and any assistance will be much appreciated. Thanks guys!
Update
A quick note that Heroku doesn't support the HttpRequest() class from what I've experienced, however, cURL works great. Also, I didn't mention it, but I was actually wanting a notification message to be sent, not just a data message. So, my final code looked like the following:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://fcm.googleapis.com/fcm/send",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\n
\"notification\" : {\n
\"body\" : \"Goku\",\n
\"title\" : \"Over 9000\",\n
},\n
\"to\" : \"MY_FCM_TOKEN\"\n
\"priority\" :
\"high\"\n
}",
CURLOPT_HTTPHEADER => array(
"authorization: key=MY_SERVER_KEY",
"cache-control: no-cache",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
In your code
'http' => array(
'header' => "Content-type: application/json\r\n" .
"Authorization: key=MY_SERVER_KEY\r\n",
'method' => 'POST',
'data' => http_build_query($data),
'to' => 'MY_FCM'
)
you have to send data and to inside the key 'content'.
/* $mydata contains 'data' and 'to' */
'http' => array(
'header' => "Content-type: application/json\r\n" .
"Authorization: key=MY_SERVER_KEY\r\n",
'method' => 'POST',
'content' => http_build_query($mydata)
)
These are few recommended ways to send fcm notification using php
HttpRequest
$request = new HttpRequest();
$request->setUrl('https://fcm.googleapis.com/fcm/send');
$request->setMethod(HTTP_METH_POST);
$request->setHeaders(array(
'cache-control' => 'no-cache',
'content-type' => 'application/json',
'authorization' => 'key=YOUR_FCM_API_KEY'
));
$request->setBody('{
"data" : {
"name" : "Goku",
"power_level" : "Over 9000",
"fighting_skill" : "excellent"
},
"to" : "FCM_ID_OF_RECIEVER"
}');
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
pecl_http
<?php
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->append('{
"data" : {
"name" : "Goku",
"power_level" : "Over 9000",
"fighting_skill" : "excellent"
},
"to" : "FCM_ID_OF_RECIEVER"
}');
$request->setRequestUrl('https://fcm.googleapis.com/fcm/send');
$request->setRequestMethod('POST');
$request->setBody($body);
$request->setHeaders(array(
'cache-control' => 'no-cache',
'content-type' => 'application/json',
'authorization' => 'key=YOUR_FCM_API_KEY'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
cURL
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://fcm.googleapis.com/fcm/send",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\n \"data\" : {\n \"name\" : \"Goku\",\n \"power_level\" : \"Over 9000\",\n \"fighting_skill\" : \"excellent\"\n },\n \"to\" : \"FCM_ID_OF_RECIEVER\"\n}",
CURLOPT_HTTPHEADER => array(
"authorization: key=YOUR_FCM_API_KEY",
"cache-control: no-cache",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}