Guzzle api call not working on droplet but working locally - php

Hi I'm trying to get a token from an api but no matter what I try on the droplet I get an invalid client every single time, the code is the same locally and on the droplet, currently working on local but not on the droplet.
This is the code
return Cache::rememberForever('payment_token', function () {
$client = new Client(['http_errors' => false]);
$params = [
'client_id' => env('CLIENT_ID'),
'client_secret' => env('CLIENT_SECRET'),
'grant_type' => 'client_credentials',
];
$headers = [
'Accept' => 'application/json',
];
$response = $client->request('POST', 'https://apipay.io/auth/token/', [
'json' => $params,
'headers' => $headers
]);
$res_body = json_decode($response->getBody()->getContents());
return $res_body->access_token;
});
The url for the post isn't a real one, I don't really think it's wise to post the real one as it doesn't work without the client_id and client_secret which I can't post here.
Is there a reason why the droplet would interfere with this? What can I do to fix this?

Double-check the remote .env file and make sure, that it's not some outdated, cached version of it (which env() would then return). Laravel has this feature, which can indeed be quite tricky, while not considering that (eg. it just doesn't work for no apparent reason). php artisan cache:clear clears the config-cache and php artisan config:cache builds it up again; I even think that production uses a cached config by default (which may be the actual difference there).

Related

Trying to use bulksms.com API using guzzle in Laravel but returning errors

I have been trying to use guzzle for sending bulk sms from bulksms.com and it is returning this error,
guzzlehttp\exception\clientexception client error: post
https://api.bulksms.com/v1/messages resulted in a 401 full
authentication is required to access this resource response: : "type"
"https://developer.bulksms.com/json/v1/errors#authentication-failed
My code
$client = new Client([
'base_uri'=>'https://www.bulksms.com/',
'timeout'=>'900.0'
]);
//$result = $client->post('', [
// 'form_params' => [
// 'sample-form-data' => 'value'
// ]
//]);
$result = $client->request('POST','https://api.bulksms.com/v1/messages', [
'form_params' => [
'username' => 'username',
'password' => '****',
'sender' => 'my appname',
'recipients' => '+5555555555',
'message' => 'Testing message',
]
]);
Other people have already pointed you towards using authentication correctly, and using JSON as the format of your request. Additionally, you're using the wrong variable names. For example, the documentation uses the variable name to, and you have used recipients instead (maybe you copied and pasted that code from somewhere else?).
The documentation has a PHP code sample the uses curl, at: https://www.bulksms.com/developer/json/v1/#tag/Message - why not use that as a basis, and then convert it to a working Guzzle request, as a starting point?
Did you have a look at the Authentication section in the API docs?
You should authenticate with the API using HTTP Basic Auth.

Docker not responding on PHPUnit test

I am using Docker in my PHP project and everything has been working fine until now.
My API has an endpoint that needs to call another endpoint within the same API. So, doing a post to /hello will make, eventually a call to /x.
In order to make that call I do the following:
$client = new Client([
'base_uri' => $url,
'headers' => [
'Accept' => 'application/hal+json',
'Content-Type' => 'application/json',
],
]);
$response = $client->post('/x', [
'form_params' => [
'username' => $email,
'password' => $password,
],
]);
Where the URL is the exactly the same as the first one, but for the new endpoint. For example, if the POST is for: www.mydomain.com:8880/hello, the new call will be made to www.mydomain.com:8880/x.
Now, this is working fine with the exception of the tests. PHPUnit (which runs inside a docker container) starts its web server on localhost:8880, and when making that second call (so it will try to call localhost:8880/x) it will be hanging forever.
I've tried changing that second call to 127.0.0.1:8880/x, but that didn't work either.
Any ideas on what the problem is and how can it be fixed?
Thanks!

ERROR : Guzzle Will not follow more than 1 redirects Drupal 8

i want to ask something confusing,
i had guzzle script in drupal 8 like this
$client = \Drupal::service('http_client');
$getUserInfo = $client->get($this->url, [
'Accept' => 'application/json',
'auth' => [
$this->authUsername,
$this->authPassword
]
]);
$resultUser = json_decode($getUserInfo->getBody());
i get error like this
error
but this is weird sometime this error missing but sometime it was appear, i dont know what is happen
and not just in that script but in every Guzzle request
i try
increase the maximum redirect to 1000 but its not work
disabled guzzle redirect but its stil not work
my analys
i test the API with POSTMAN everything is fine
and i had project with laravel in same server with the same API and its work
its just happen in drupal project in that server,
but in another server its fine
may someone had a same problem
Please advise
Thankyou
Have you tried to increase maximum redirects?
$client->get($this->url, [
'headers' => [
'Accept' => 'application/json',
],
'auth' => [
$this->authUsername,
$this->authPassword
],
'allow_redirects' => [
'max' => 5,
]
]);
P.S. Also you have a mistake with 'Accept': it should be inside the 'headers' container.

Laravel 5.1 Send mail to all users in foreach [GuzzleHttp\Exception\ClientException] Client error: 400

I'm trying to send an email to all the users in the database, but I'm getting the following error: [GuzzleHttp\Exception\ClientException] Client error: 400.
Here's my code:
$users = App\User::all();
foreach($users as $user) {
$code = new App\Code();
$code->code = str_random(10);
$code->save();
Mail::send('emails.code', ['code' => $code], function($message) use ($user)
{
$message->to($user->email)->from('foo.bar#gmail.com', 'Foo Bar')->subject('New code, new chances!');
});
}
[GuzzleHttp\Exception\ClientException] Client error: 400
is for URL not found
Check for host url in config/mail.php, host url might be wrong
Not sure if you have got it working but I had the exact same problem today and I had no idea what went wrong as I did the exact same implementation just in my previous Laravel project with mailgun. Then I found the issue in the configuration.
So, here is the glitch..I don't know in which version it was changed, but in config/services.php the mailgun config is now like this,
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
where it was like this before as far as I can remember,
'mailgun' => [
'domain' => env('MAIL_DOMAIN'),
'secret' => env('MAIL_SECRET'),
],
so in my .env file, I was only referencing MAIL_DOMAIN and MAIL_SECRET environment variables but I just realised in the services.php file, it's actually referencing different environment variables - MAILGUN_DOMAIN and MAILGUN_SECRET.
So I've just added these environment variables, cleared the config cache and it is working perfectly now.
(I am working with Laravel 5.1.23 version BTW)
Hope this helps. Thanks.

How do I do HTTP basic authentication using Guzzle?

I want to do basic access authentication using Guzzle and I am very new to programming. I have no clue what to do. I tried to do this using curl but my environment requires using guzzle.
If you're using Guzzle 5.0 or newer, the docs say that basic auth is specified using the auth parameter:
$client = new GuzzleHttp\Client();
$response = $client->get('http://www.server.com/endpoint', [
'auth' => [
'username',
'password'
]
]);
Please note that the syntax is different if you're using Guzzle 3.0 or earlier. The constructor is different, and you also need to explicitly use the send method on a request to get a response:
$client = new Guzzle\Http\Client();
$request = $client->get('http://www.server.com/endpoint');
$request->setAuth('username', 'password');
$response = $request->send();
A brief addendum
In response to #Matthwew-Knill, yes, you can set a default authorization and implicitly have Guzzle send it in each further request. #Nick's answer is on point. The client constructor takes every parameter you could think of and then some.
Another approach, if you want to get creative, would be to instantiate the client passing it default headers to send on every further request. Simple auth is, after all, an Authorization header. It's computed as:
$client = new Client([
'headers'=>[
'Authorization'=> Basic base64_encode(<username>:<password>)
]
]);
Last but not least please note that filling a simple auth dialog happens only once (upon the virst visit of a given session). This is usually achieved by setting a cookie on the visitor's browser. That cookie in turn contains enough info for the server to identify its matching active session.
Usually, Guzzle requests are stateless, but you can configure Guzzle with a middleware chain to either modify request or responses, for debug purposes and, for this use case, to remember cookies, thus becoming partially stateful.
Please check the detailed procedure in Guzzle Docs. The important thing is that, by instantiating the client with a cookiejar middleware, therefore having the client include it from then on, the first request will remember the server's set-cookie header, and will send it as every further cookie header, making the server recognize the client as a logged in user. Of course, you could also inspect the first response's headers yourself and send its value from then on.
There might be other ways, but I can't think of another right now.
In additional to #amenadiel answer. Sometimes handy specify auth parameters in constructor:
$client = new Client([
'auth' => ['username', 'password'],
]);
Then every request will use this default auth parameters.
This dint work when I used Guzzlev6 and used the advice from #amenadiel. When you use curl, your syntax would look something like
curl -u someone#gmail.com:password http://service.com
behind the scenes it actually takes the "someone#gmail.com:password" bit, base64 encodes it and sends the request with an "Authorization" Header with the encoded value. For this example, that will be:
Authorization: Basic c29tZW9uZUBnbWFpbC5jb206cGFzc3dvcmQ=
Advice from #amenadiel appended an "auth: username,password" header and hence, my authentication kept failing. To achieve this successfully, just craft the header when you are instantiating a Guzzle Client request, i.e
$client = new GuzzleHttp\Client();
$credentials = base64_encode('someone#gmail.com:password');
$response = $client->get('http://www.server.com/endpoint', [
'Authorization' => ['Basic '.$credentials]
]);
That would append the header as curl would, and whatever service you are trying to connect to will stop yelling at you,
Cheers.
According to the Guzzle 6 documentation, you can do a request with basic authorization as simple as this:
$client = new Client();
$response = $client->request(
'POST', /*instead of POST, you can use GET, PUT, DELETE, etc*/
$url,
[
'auth' => ['username', 'password'] /*if you don't need to use a password, just leave it null*/
]
);
echo $response->getBody();
NOTE: You don't need to use base64_encode() at all because it already does it before the request.
I've tested and it works :)
See more at: Guzzle 6 Documentation
$response = $client->request( 'GET', 'your_url', [
'auth' => [
'your_username',
'your_password'
],
'headers' => [
'if you want to pass something in the headers'
]
]
);
You can also configure the auth params when instantiating the client instead of adding it to each request:
$this->client = new \GuzzleHttp\Client([
'base_uri' => $this->endpoint,
'headers' => [
'Authorization' => ['Basic '.base64_encode($this->username.':'.$this->password)],
],
]);
Here are the various doc links for Guzzle 6:
Creating a Client
Request Options
Auth Request Options
According to what #bourgeois247 said about base64 encoding, the following worked perfectly for me on Guzzle 6:
$client = new Client();
$credentials = base64_encode('username:password');
$response = $client->post('url',
[
'headers' => [
'Authorization' => 'Basic ' . $credentials,
],
]);
If you use it with symfony, you can also define it in your configuration file (config/packages/eight_points_guzzle.yaml for symfony4 or flex or config.yml for the other version)
In your configuration file :
eight_points_guzzle:
clients:
your_service:
# Write here the host where to do requests
base_url: "yourURL"
options:
timeout: 30
auth:
- yourLogin # login
- yourPassword # password
plugin: ~
Then, in your service, controller, etc....
$client = $this->getContainer()->get('eight_points_guzzle.client.your_service');
$response = $client->get('yourRoute');
See : https://packagist.org/packages/eightpoints/guzzle-bundle

Categories