How to comunicate with an API with GuzzleHttp - php

I'm trying to communicate to an API with laravel using guzzleHttp but I can't receive nothing.
If I test in postman returns me information.
In postman I set the configuration as you see in image:
In code I'm trying to do that:
$token = env('API_TOKEN');
$company = env('API_COMPANY_ID');
$link = 'https://xpto.pt/APIs.aspx/Con';
$data = array('token' => $token, 'empresa' => $company);
$data = json_encode($data);
echo $data;
$client = new Client();
$request = $client->post($link, ['raw'=>$data]);
$response = $request->send();
dd($response);
Thank you

Related

Json request with the help of php

I am trying to connect API after jwt token. But this my first time experience with API. So Company give me to codes On is "Generate JWT token" other is httpRequest with php. Company give me Object of class "$request = new HttpRequest();". But i don't know to work this object.
Create a jwt at your end to request a token (PHP).
Replace {CLIENT_ID}, {CLIENT_SECRET} in php code.
This code works fine.
function base64url_encode($str) {
return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
}
function generate_jwt($headers, $payload, $secret = 'CLIENT_SECRET') {
$headers_encoded = base64url_encode(json_encode($headers));
$payload_encoded = base64url_encode(json_encode($payload));
$signature = hash_hmac('SHA256', "$headers_encoded.$payload_encoded", $secret, true);
$signature_encoded = base64url_encode($signature);
$jwt = "$headers_encoded.$payload_encoded.$signature_encoded";
return $jwt;
}
$headers = array('alg'=>'HS256','typ'=>'JWT');
$payload = array('aud'=>'https://s1.serviceaccountsapi.example.net/v1/{client_id}/api/token', 'iss'=>'CLIENT_ID', 'expiry'=> 3600);
$jwt = generate_jwt($headers, $payload);
echo $jwt;
To request in PHP:
This is not working. Because this object don't have class . So i don't know what i write in this class.
$request = new HttpRequest();
$request->setUrl('https://s2.serviceaccounts.example.net/v1/{CLIENT_ID}/api/token');
$request->setMethod(HTTP_METH_POST);
$request->setHeaders(array(
'content-type' => 'application/x-www-form-urlencoded'
));
$request->setContentType('application/x-www-form-urlencoded');
$request->setPostFields(array(
'assertion' => 'Bearer {PUT YOUR TOKEN HERE WITHOUT BRACES}',
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
Seems like it's proposing you to implement an HttpRequest class following the suggested interface.

How to send a correct authorization header for basic authentication using guzzle

How to send a correct authorization header for basic authentication using guzzle
use GuzzleHttp\Client;
$username='EFDEMO';
$password='EFDEMO';
$client = new Client(['auth' => [$username, $password]]);
$res = $client->request('GET', 'https://mb-
rewards.calusastorefront.p2motivate.com/client/json.php/
getMemberAccount');
$res->getStatusCode();
$response = $res->getBody();
echo $response;
the error I am getting
{"statusCode":"Error","error":
{"errorCode":"400","errorMessage":"Authentication Header ID field must
match Basic Authentication Username"}}
Referring to documentation you should pass the auth parameter in request method instead of client's constructor:
$client = new Client();
$res = $client->request(
'GET',
'past-url-here',
['auth' => [$username, $password]]
);
I solved it like below
<?php
require '../x_static_libs/guzzle/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();
$username = 'xxxxxx';
$password = 'xxxxxxxx';
$token = 'xxxxxxxxxxxxxxxxxxxx';
$url = 'https://ervb-rewards.com/client/json.php';
$api_token =
base64_encode(json_encode(['id'=>'xxxxxxx','token'=>'xxxxxxxxxxxxxxxxxxxxxx']));
$res = $client->request(
'GET',
$url.'/getMemberAccount',
['auth' => [$username,$api_token]]
);
$jsonData = json_decode($res->getBody(), true);
echo "<pre>";
print_r($jsonData);
echo "</pre>";

How to send a message to specific connectionId to aws api gateway websockets?

I am using this code to establish a new connection on user device.
var socket = new WebSocket("wss://cdsbxtx2xi.execute-api.us-east-2.amazonaws.com/test");
socket.onmessage = function (event) {
json = JSON.parse(event.data);
connectionId = json.connectionId;
document.cookie = "connection_id="+connectionId;
console.info(json);
}
Suppose from this request I get connectionId CLO5bFP1CYcFSbw=
Another user from another device also established a new connection with connectionId Cs42Fs5s5yuSbc=. Now how can I send a message from user 2 device to user 1?
I already tried this. I don't know this is right way or not but still, i am open for any suggestion.
use Aws\Signature\SignatureV4;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Aws\Credentials\Credentials;
$client = new GuzzleHttp\Client();
$credentials = new Credentials("XXXXXXXXXX","XXXXXXXX");
$url = "https://cdsbxtx2xi.execute-api.us-east-2.amazonaws.com/test/#connections/CLO5bFP1CYcFSbw=";
$region = 'us-east-2';
$msg['action'] = 'sendmessage';
$msg['data'] = 'hello world';
$msg = json_encode($msg);
$request = new Request('POST', $url, '["json"=>$msg]');
$s4 = new SignatureV4("execute-api", $region);
$signedrequest = $s4->signRequest($request, $credentials);
$response = $client->send($signedrequest);
echo $response->getBody();
This code keeps on loading and finally throws gateway timeout error.
I expect that user 2 should be able to send message to any specific connectionId over wss or https.
I tried https by signing this request but signing doesn't works. I am getting an error with the signing part
After struggling with this problem for the last 3 days finally I found the solution. None of the previously mentioned solutions on StackOverflow was working for me.
This is the correct solution. I hope this will be helpful to someone.
use Aws\Signature\SignatureV4;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Aws\Credentials\Credentials;
$client = new GuzzleHttp\Client();
$credentials = new Credentials(accessKeyId, secretAccessKey);
$url = "https://xsdsdsd.execute-api.us-east-2.amazonaws.com/test/#connections/CNtBveH2iYcCKrA=";
// CNtBveH2iYcCKrA= is connectionid
$region = 'us-east-2';
$msg['action'] = 'sendmessage';
$msg['data'] = 'hello world';
$msg = json_encode($msg);
$headers = array('Content-Type => application/x-www-form-urlencoded');
$request = new GuzzleHttp\Psr7\Request('POST', $url, ['Content-Type' => 'application/json'], $msg);
$signer = new Aws\Signature\SignatureV4('execute-api', $region);
$request = $signer->signRequest($request, $credentials);
$headers = array('Content-Type => application/x-www-form-urlencoded');
$client = new \GuzzleHttp\Client([ 'headers' => $headers]);
$response = $client->send($request);
$result = $response->getBody();
Hey you can use the Connection URL to send message also.
Connection url : https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/#connections
To find go to : Aws console > Api gateway > api > your_api > dashboard their you will find your connection url.
Use php cURL method because its easy and fast as compare to GuzzleHttp
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/#connections/{YOUR_CONNECTION_ID_OF_USER}',
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 =>'{"message" : "Hello world"}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;

Create function to send requests to an API

I have an API that I am trying to create a function for to send requests, the docs are here: http://simportal-api.azurewebsites.net/Help
I thought about creating this function in PHP:
function jola_api_request($url, $vars = array(), $type = 'POST') {
$username = '***';
$password = '***';
$url = 'https://simportal-api.azurewebsites.net/api/v1/'.$url;
if($type == 'GET') {
$call_vars = '';
if(!empty($vars)) {
foreach($vars as $name => $val) {
$call_vars.= $name.'='.urlencode($val).'&';
}
$url.= '?'.$call_vars;
}
}
$ch = curl_init($url);
// Specify the username and password using the CURLOPT_USERPWD option.
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
if($type == 'POST') {
curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
}
// Tell cURL to return the output as a string instead
// of dumping it to the browser.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//Execute the cURL request.
$response = curl_exec($ch);
// Check for errors.
if(curl_errno($ch)){
// If an error occured, throw an Exception.
//throw new Exception(curl_error($ch));
$obj = array('success' => false, 'errors' => curl_error($ch));
} else {
$response = json_decode($response);
$obj = array('success' => true, 'response' => $response);
}
return $obj;
}
So this determintes whether its a GET or POST request, but the response being returned on some calls is that GET is not supported or POST is not supported, although I am specifying the correct one for each call.
I think I have the function wrong somehow though and wondered if someone could assist me in the right direction? As I've also noticed, I need to allow for DELETE requests too.
for the easier life, try guzzle.
http://docs.guzzlephp.org/en/stable/
you can make a request like this :
use GuzzleHttp\Client;
$client = new Client();
$myAPI = $client->request('GET', 'Your URL goes here');
$myData = json_decode($myAPI->getBody(), true);
then you can access the data like an array
$myData["Head"][0]
The problem is in $url you try to create for GET request.
Your $url for GET request looks like:
GET https://simportal-api.azurewebsites.net/api/v1/?param1=val1&param2=val2
but from documentation you can clearly see that you $url should be:
GET https://simportal-api.azurewebsites.net/api/v1/param1/val1/param2
for ex.:
GET https://simportal-api.azurewebsites.net/api/v1/customers/{id}
GuzzleHttp is the standard way to work with web service.
You can use auth parameter to send your authentication detail. Also, you can use Oath or Beer token whatever your convenient method is. If you try to call service via a token method, keep in mind you will need to pass authorization by header instead of auth.
See this GuzzleHttp authentication via token. Also, you can catch exception very quickly. See Handle Guzzle exception and get HTTP body
Try below code got from official site ;)
$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.github.com/user', [
'auth' => ['user', 'pass']
]);
echo $res->getStatusCode();
// "200"
echo $res->getHeader('content-type')[0];
// 'application/json; charset=utf8'
echo $res->getBody();
// {"type":"User"...'
// Send an asynchronous request.
$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
$promise = $client->sendAsync($request)->then(function ($response) {
echo 'I completed! ' . $response->getBody();
});
$promise->wait();
You can find more about GuzzleHttp request here: http://docs.guzzlephp.org/en/stable/quickstart.html#making-a-request
Hope this what you want!
I think you should try to use Postman Tool to request to that API first. If postman does the job it means problem in your PHP code. But if you already used postman and still can't fetch response, so it may be problem with that API. Like URL block.

Strava Api issue

I'm using this composer package https://github.com/basvandorst/StravaPHP
The OAUTH is working fine and its generating me the JSON with the access token and user id, etc..
But whenever I try to use other function it returns me 404 not found.
Output is this :
{"token_type":"Bearer","access_token":"077058e0c800881c72a4b10a04a520d5898d4e3e","athlete":{"id":35670467,"username":"amir_do","resource_state":2,"firstname":"Amir","lastname":"Do","city":null,"state":null,"country":null,"sex":"M","premium":false,"summit":false,"created_at":"2018-10-13T13:55:41Z","updated_at":"2018-10-13T13:56:25Z","badge_type_id":0,"profile_medium":"https://lh5.googleusercontent.com/-ku6v9lKNgYY/AAAAAAAAAAI/AAAAAAAAAAA/ABtNlbASj8KhClhwnVYVqRrEG2oiYzWPbA/mo/photo.jpg","profile":"https://lh5.googleusercontent.com/-ku6v9lKNgYY/AAAAAAAAAAI/AAAAAAAAAAA/ABtNlbASj8KhClhwnVYVqRrEG2oiYzWPbA/mo/photo.jpg","friend":null,"follower":null,"email":"goncalomaia97#gmail.com"}}
35670467
Client error: `GET https://www.strava.com/api/athletes/35670467/stats?access_token=077058e0c800881c72a4b10a04a520d5898d4e3e` resulted in a `404 Not Found` response: {"message":"Record Not Found","errors":[{"resource":"resource","field":"path","code":"invalid"}]}
And this is my current callback.php page code:
<?php
include 'vendor/autoload.php';
use Strava\API\Client;
use Strava\API\Exception;
use Strava\API\Service\REST;
session_start();
$client = new GuzzleHttp\Client();
global $connect;
require_once("configs/database.php");
$connect = new mysqli($config['database']['host'],$config['database']['user'],$config['database']['pass'],$config['database']['db']);
$code = $_GET['code'];
$state = $_GET['state'];
$scope = $_GET['scope'];
$user = $_SESSION['username'];
$check = $connect->query("SELECT * FROM users WHERE email = '$user'");
$fetch = $check->fetch_array(MYSQLI_ASSOC);
$apix = $fetch['api'];
$api_secretx = $fetch['api_secret'];
$client = new GuzzleHttp\Client();
$data = [
"client_id" => $apix,
"client_secret" => $api_secretx,
"code" => $code
];
$result = $client->post('https://www.strava.com/oauth/token', ['json' => $data]);
print "<pre>";
print_r( $result->getBody()->getContents() );
print "</pre>";
$bodyb = $result->getBody();
$varx = json_decode((string) $bodyb, true);
$token = $varx['access_token'];
$id = $varx['athlete']['id'];
$_SESSION['token'] = $token;
printf($id);
try {
// REST adapter (We use `Guzzle` in this project)
$adapter = new \GuzzleHttp\Client(['base_uri' => 'https://www.strava.com/api/v3']);
// Service to use (Service\Stub is also available for test purposes)
$service = new \Strava\API\Service\REST($token, $adapter);
// Receive the athlete!
$client = new Client($service);
$athlete = $client->getAthleteStats($id);
print_r($athlete);
} catch(Exception $e) {
print $e->getMessage();
}
$adapter = new \GuzzleHttp\Client(['base_uri' => 'https://www.strava.com/api/v3']);
Change that to this (It should be trailing) :
$adapter = new \GuzzleHttp\Client(['base_uri' => 'https://www.strava.com/api/v3/']);

Categories