I am trying to perform CURL get request in guzzlehttp to check if a user exists in a CRM. Whenever I try to perform the request I get the following error in the title, I haven't been able to find any resources online for this specific problem. Any ideas would be super helpful, if you require any additional info please let me know in the comments.
Included packages:
require(__DIR__ . "/../../vendor/autoload.php");
require_once(__DIR__ . "/../../helpers/Validation.php");
use Symfony\Component\Dotenv\Dotenv;
use GuzzleHttp\Client;
use GuzzleHttp\Request;
use GuzzleHttp\RequestOptions;
use GuzzleHttp\Psr7;
use GuzzleHttp\Stream\Stream;
use Drupal\Core\Site\Settings;
// Load our environment variables
$dotenv = new Dotenv();
$dotenv->load(__DIR__ . "/../../.env");
private function checkDuplicate() {
// If no errors we can submit the registrant
// \Drupal::logger('signup')->notice("access token", print_r($this->_accessToken, TRUE));
if(!$this->_errors) {
$checkNewUser = new Client();
try {
$options = [
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
'Authorization' => "Bearer " . $this->_accessToken
],
"query" => '$filter=email%20eq%20"' .$this->_email . '"&$fields=Contact Key,First Name,Last Name'
];
$result = $checkNewUser->get($_ENV['REST_API_URL'], $options);
} catch (RequestException $e) {
\Drupal::logger('signup')->error("error " . print_r($e->getRequest(), TRUE));
if ($e->hasResponse()) {
\Drupal::logger('signup')->error("error " . print_r($e->getRequest(), TRUE));
echo $e->getRequest() . "\n";
\Drupal::logger('signup')->error("error " . print_r($e->getResponse(), TRUE));
}
}
}
I have a post request function to gain an access token that works correctly.
private function getAccessToken() {
try {
$requestAccessToken = new Client();
$options = [
'headers' => [
'Accept' => 'application/json',
],
"form_params" => [
"grant_type" => "client_credentials",
"client_id" => $_ENV["CLIENT_ID"],
"client_secret" => $_ENV["CLIENT_SECRET"]
]
];
$result = $requestAccessToken->post($_ENV['CLIENT_API_URL'], $options);
return (string) $result->getBody();
}
catch(Exception $error) {
\Drupal::logger('signup')->error("error " . $error-getMessage());
}
}
The issue was caused due to guzzlehttp being directly supported in drupal-8, caused a confliction with the package installed via composer.
After removing composer libraries for guzzle and use the following documentation:
https://www.drupal.org/docs/8/modules/http-client-manager/introduction
Related
I'm trying to make a request with my other endpoint, using GuzzleHttp in laravel, but the token isn't authorizing it. I believe it's in the way I'm going. Anyone know how to fix this? This is my code.
public function productRecommendation($rowPerPage,$keywords, $page){
try{
$request = request();
$token = $request->bearerToken();
$client = new \GuzzleHttp\Client();
$promise = $client->request('GET', $this->sellerUrl.'recommended', [
'headers' => ['Authorization' => "Bearer {$token}"],
'query' =>
[
'rowPerPage' => $rowPerPage,
'page' => $page,
'keywords' => $keywords,
],
]);
$response = (string) $promise->getBody();
return json_decode($response, true);
}
catch (Exception $e){
return $e;
}
}
You are getting the bearer token of your first application using $request->bearerToken() and send it to your second application for authorization which must not work;
You need to get a working token from your second application. You can either generate a token in your second application and copy it inside your current $token variable, or first call the login endpoint of second application with your credentials and use that token.
By the way, Laravel now supports a guzzle wrapper called Illuminate\Support\Facades\Http which makes things lot easier, you can rewrite your code like this:
public function productRecommendation($rowPerPage, $keywords, $page)
{
try{
$token = "some valid token from second endpoint";
$response = Http::withToken(
$token
)->get(
$this->sellerUrl . 'recommended',
[
'rowPerPage' => $rowPerPage,
'page' => $page,
'keywords' => $keywords,
]
);
return response()->json(
json_decode($response->body(), true)
);
}
catch (Exception $e){
return $e;
}
}
Hi i want to consume a service and i use laravel 5.x with guzzle with this code i can send request and i use the correct api-key but i always obtain 403 forbidden....
public function searchP(Request $request) {
$targa = request('targa');
$client = new \GuzzleHttp\Client();
$url = 'https://xxx.it/api/xxx/xxx-number/'.$targa.'/xxx-xxxx';
$api_key ='xxxxxcheepohxxxx';
try {
$response = $client->request(
'GET',
$url,
['auth' => [null, $api_key]]);
} catch (RequestException $e) {
var_dump($e->getResponse()->getBody()->getContent());
}
// Get JSON
$result = $response->json();
}
Why? I cannot understand
In postman i write in the AUTHORIZATION label this
key : x-apikey
value: xxxxxcheepohxxxx
Add to header
and it works.
i also tried this
.... try {
$response = $client->request('GET',$url,[
'headers' => [
'x-apikey', $api_key
]
]);
} catch .....
but doesn't work
Thx
it should be this, you have a typo
.... try {
$response = $client->request('GET',$url,[
'headers' => [
'x-apikey'=> $api_key
]
]);
} catch .....
I'm trying to execute a Google Cloud Function through PHP, but failing to authenticate when all I have is the service_account json file.
I'm using GuzzleHttp as the function returns a Promise.
What I did so far:
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Auth\Middleware\AuthTokenMiddleware;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\HandlerStack;
use Psr\Http\Message\ResponseInterface;
$scopes = [
'https://www.googleapis.com/auth/cloud-platform',
];
$credentials = new ServiceAccountCredentials($scopes, [
'client_email' => "<email>",
'client_id' => "<client_id">,
'private_key' => "<private_key>",
]);
$googleAuthTokenMiddleware = new AuthTokenMiddleware($credentials);
$stack = HandlerStack::create();
$stack->push($googleAuthTokenMiddleware);
$config = array('handler' => $stack,'auth' => 'google_auth');
$httpClient = new Client($config);
$promise = $httpClient->requestAsync("POST", "<function_url>", ['json' => ['data' => ""]]);
$promise->then(
function (ResponseInterface $res) {
echo "<pre>";
print_r($res->getBody());
echo "</pre>";
},
function (RequestException $e) {
echo "<pre>";
print_r($e->getRequest()->getHeaders());
echo "</pre>";
echo $e->getMessage() . "\n";
echo $e->getRequest()->getMethod();
}
);
$promise->wait();
References:
ServiceAccountCredentials: From namespace Google\Auth\Credentials;
AuthTokenMiddleware: From namespace Google\Auth\Middleware;
HandlerStack: From GuzzleHttp
Client: From GuzzleHttp
Http Response From Above Code
`401 Unauthorized` response: {"error":{"status":"UNAUTHENTICATED","message":"Unauthenticated"}} POST
My Cloud Function
My Cloud Function checks for authentication as follow:
exports.testFunction = functions.https.onCall((data, context) => {
if (!context.auth) {
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
}
return "Hooraaay!";
});
What am I doing wrong? How can I successfully authenticate?
My code is as follows:
require_once $DOCUMENT_ROOT.'/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
...
if($token!='' && $email!='')
{
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://graph.microsoft.com/v1.0/me/sendmail', [
'headers' => [
'Authorization' => 'Bearer ' . $token,
'Content-Type' => 'application/json;odata.metadata=minimal;odata.streaming=true'
],
'body' => $email
]);
if($response.getStatusCode() === 201) {
exit('<h1>Email sent, check your inbox</h1>');
} else {
exit('<h2>There was an error sending the email.</h2> Status code: ' . $response.getStatusCode());
}
}
I keep getting an error Call to undefined function getStatusCode().
I know I need to add another use, but I have tried everything and can't get it to work, same error every time.
Fixed it. Copied the code from Microsoft, it is supposed to be:
if($response->getStatusCode() === 202)
Also it is 202 not 201 for success
I've created a custom Provider for Laravel Socialite.
The authentication part is going well until i'll try to call the user method.
Not sure what's going wrong.
Method documentation at wunderlist
My code:
/**
* {#inheritdoc}
*/
protected function getUserByToken($token)
{
$response = $this->getHttpClient()->get('https://a.wunderlist.com/api/v1/users', [
'X-Access-Token: ' . $token . ' X-Client-ID: ' . $this->clientId
]);
return json_decode($response->getBody(), true);
}
I get the following error:
InvalidArgumentException in MessageFactory.php line 202:
allow_redirects must be true, false, or array
Do i miss things in the options array?
Jos
Actually socialite is not supposed to do something like this. But instead you may use Guzzle. There is a good video at laracasts. Just search for Easy HTTP Requests. And here's the code that you may use for guzzle:
$client = new \Guzzle\Service\Client('a.wunderlist.com/api/v1/');
$response = $client->get('user')->send();
// If you want this response in array:
$user = $response->json();
Just read the docs here.
When using this with straight forward curl there is no issue.
As far as i can see the issue lies in the headers i'll parse.
The following solution is something i can live with, although it's not perfect.
$headers = array();
$headers[] = 'X-Access-Token: ' . $token;
$headers[] = 'X-Client-ID: ' . $this->clientId;
$response = $this->getHttpClient()->get('a.wunderlist.com/api/v1/user', [
'config' => [
'curl' => [
CURLOPT_POST => 0,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => false
]
]
]);
return json_decode($response->getBody(), true);