I am trying to access an API using Guzzle in Laravel 5.5.
The command in curl looks like:
curl http://apiurl.com/getRequest -d "api_key=token_value"
Now using Guzzle, I started to code as below:
$client = new Client(['base_uri' => 'http://apiurl.com/']);
$response = $client->request('GET', 'getRequest', [
'headers' => [
'api_key' => ['token_value']
]
]);
var_dump($response->getStatusCode());
var_dump(json_decode($response->getBody(), true));
Now I am able to see statusCode as 200 and getBody as Null. But when I use the same request using curl then I am able to see the complete data.
Could someone resolve it please?
When comparing differences between curl and Guzzle, I highly recommend using -v (curl) and the debug request option (Guzzle). The verbose output allows for visual comparison of the requests that each software is transmitting.
The curl man page indicates that -d and --data send POST requests.
(HTTP) Sends the specified data in a POST request to the HTTP server,
in the same way that a browser does when a user has filled in an HTML
form and presses the submit button. This will cause curl to pass the
data to the server using the content-type
application/x-www-form-urlencoded.
A pair of changes are required in order to send the desired request with Guzzle:
$response = $client->request('POST', $uri, [
'form_params' => [
'api_key' => $key_value,
],
]);
The first change is the type of request that is being sent (GET => POST). The second, is the usage of form_params. The form_params request option is used to send application/x-www-form-urlencoded POST requests.
Related
I have 5 applications that use the same sanctum API for authentication. What I really want to do is to make a POST request sanctum API from another application. I do GET requests like the below and it's working. But when I make a POST request it returns csrf token mismatch error.
So could someone please tell me is it possible to make a post request into a sanctum API via Client?
$response = $client->get('http://localhost:8000/api/user', [
'headers' => [
'accept' => 'application/json',
'cookie' => $request->header('cookie'),
'referer' => $request->header('referer'),
]
]);
Thanks
i use Bearer instead of cookie ,
in sanctum laravel reads access tokens from Authorization in header.
this is how i make request from laravel client to sanctum (an example of my code):
$response = Http::withHeaders([
"Accept"=> "application/json",
"Authorization" => "Bearer " . Cookie::get("Laravel")
])
->post("http://localhost:8088/api/v1/url/find", ["find" => $request->find]);
i send my headers with method withHeaders as an associative array
and send my post body with post method second argument.
read more here : https://laravel.com/docs/9.x/http-client
You're missing some headers on your requests. You need to first make a request to "/sanctum/csrf-cookie", what gives you a CSRF token. Then you pass that token as the value for the header "X-CSRF-TOKEN". Sanctum documentation explains it very well. https://laravel.com/docs/8.x/sanctum#spa-authenticating
Wish you luck!
hope you all are doing well. I am stuck with an issue since couple of hours and could not be able to resolve it. Please have a look on error
enter image description here
I am trying to generate refresh token. Access_token generated successfully that is expired after 20 minutes. refresh token could not be generated
$client = new Client();
$res = $client
->request("POST",
"https://test.salesforce.com/services/oauth2/token",[
'body'=> json_encode([
'grant_type'=>'refresh_token',
'client_id'=>Config::get('forrest.info.client_id'),
'client_secret'=>Config::get('forrest.info.client_secret'),
'Authorization'=>'Bearer 00D3H0000008olE!ARYAQOzGGJDDIaygn7GokNk4T319XlDwwBXIDYPkJfej74dfhFT3CMDvBD2pZBQK_x.v2amiRe5Y29ZNXMp9EOA6ZTYyqrTW',
'access_token'=>'00D3H0000008olE!ARYAQOzGGJDDIaygn7GokNk4T319XlDwwBXIDYPkJfej74dfhFT3CMDvBD2pZBQK_x.v2amiRe5Y29ZNXMp9EOA6ZTYyqrTW',
])
]
);
dd ($res->getStatusCode());
any help or comment would be highly appreciated! thank for your time.
It seems like this error is returned from SalesForce API.
Looking at their documentation, it seems that they expect to see application/x-www-form-urlencoded not json.
Try out this code:
$client = new Client();
$response = $client->request('POST', '/post', [
'form_params' => [
'grant_type' => 'refresh_token',
'client_id' => Config::get('forrest.info.client_id'),
'client_secret' => Config::get('forrest.info.client_secret'),
'Authorization' => 'Bearer 00D3H0000008olE!ARYAQOzGGJDDIaygn7GokNk4T319XlDwwBXIDYPkJfej74dfhFT3CMDvBD2pZBQK_x.v2amiRe5Y29ZNXMp9EOA6ZTYyqrTW',
'access_token' => '00D3H0000008olE!ARYAQOzGGJDDIaygn7GokNk4T319XlDwwBXIDYPkJfej74dfhFT3CMDvBD2pZBQK_x.v2amiRe5Y29ZNXMp9EOA6ZTYyqrTW',
],
]);
dd($response);
let me know if it helped.
(Not an answer but too long for a comment)
This looks weird. "Authorization Bearer" should be a http header, not part of the message's body. Are you able to do what you need in plain old Postman, SoapUI etc?
Which OAuth2 flow did you use to generate this access token? Not all flows generate refresh token, for example https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_username_password_flow.htm&type=5 says "this flow doesn't support scopes" so you get full access - but also "this response doesn’t send a refresh token."
Have you checked the connected app (place in SF where you took client id and secret from), do the OAuth2 scopes include refresh? Did you ask for refresh token (included it in the original request's grants)?
I have a laravel application setup and I'm configuring a Discord auth system.
I have sent & requested authorization & recieved a confirmation code back.
When I try to exchange the code for an access token I'm receiving a 400 bad request and I'm not sure why.
I'm new to laravel and can't seem to find any sort of error that may help to pin point the problem.
Controller function that discord redirects after authorization
public function exchange(Request $request) {
//exchange discord code for access_token
$code = Request::get('code',false);
$params = array(
'grant_type' => 'authorization_code',
'client_id' => env('CLIENT_ID'),
'client_secret' => env('OAUTH2_CLIENT_SECRET'),
'redirect_uri' => Request::root().'/discord/return',
'scope' => 'identify guilds guilds.join',
'code' => $code
);
$access_token = Http::withOptions([
'debug' => true,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded'
],
'json' => $params
])->post('https://discordapp.com/api/oauth2/token');
dd($access_token);
return redirect()->route('return.discord',['token' => $access_token->access_token]);
}
I've dumped out $params and all the data is pulling in as it should.
Guzzle dumps this:
[CONNECT] [FAILURE] severity: "2" message: "HTTP/1.1 400 Bad Request " message_code: "400" [MIME_TYPE_IS] message: "application/json" [FILE_SIZE_IS] message: "Content-Length: 26" bytes_max: "26" [PROGRESS] bytes_max: "26"
I know that 400 bad request means an issue with the data being sent along, but I can't figure out what I'm doing that's not producing the correct result. The documentation states the required content type which I have set, so I'm really scratching my head here.
Any help would be much appreciated.
Here's the Discord API documentation:
https://discord.com/developers/docs/topics/oauth2#authorization-code-grant
To anyone looking for an answer...
The "invalid grant" error is due to an issue with the Discord API and non-standard requests. I could not get the Laravel HTTP class request to work for exchanging the access token. Instead, I used native php cURL within Laravel.
As for the issue with receiving '400 bad request', that was due to using incorrect function withOptions() as oppossed to asJson()->withHeaders(). Thanks #Zachary Craig!
However, I could not use this in the end due to the problem described above.
If any others find a better solution, let me know :)!
For all who have the same problem.
The solution is to use ->asForm() before the post. This changes the handling of the data from json to form_params. This way the Discord API accepts the parameters.
return Http::asForm()->post($this->endpoint.'/oauth2/token', $data);
I want when someone message me on my clickatell number then I want to send this message on my email. I'm using the http request.I have check the http api pdf in which only showing the authentication and send message url . I want the url by whcih I get the message in my script.
I'm using the curl function for request the page.
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://api.clickatell.com/http/auth?user=demo&
password=demo&api_id=123432',
CURLOPT_USERAGENT => 'Codular Sample cURL Request',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => array(
item1 => 'value',
item2 => 'value2'
)
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
print_r($resp);
// Close request to clear up some resources
curl_close($curl);
It is working and return me the session id and ok status. similarly can I get the incoming message ?
Clickatell has a two-way service which will allow you to receive messages from their service and their implementation documentation can be read here.
In order to receive the notice via email, I would recommend opting for the HTTP callback from Clickatell's servers. This will allow you to write a small script to convert the contents into an email.
Hope that this helps you.
I have a cURL that I am trying to translate into Ruby.
the cURL is this:
curl -i -k -H "Accept: application/json" -H "Authorization: token" -H "Content-Type: image/jpeg" -H "Content-Length: 44062" --data-binary "gullfoss.jpg" http://www.someurl.com/objects
My Ruby code is this:
image = File.read('uploads/images/gullfoss.jpg')
result = RestClient.post('http://www.someurl.com/objects',image,{'upload' => image, 'Accept' => 'application/json', 'Authorization' => 'token', 'Content-Type' => 'image/jpeg', 'Content-Length' => '44062'})
The Ruby code is giving me back a 400 Bad Request. It's not a problem with Authorization or the other headers. I think the problem lies with translating --data-binary to Ruby.
Any help appreciated.
Thanks,
Adrian
There are a few things which might cause the problem.
You want to use an actual File object with RestClient, so use File.open; it returns a file object.
You are including the image object twice in your request; the actual content is not made clear from your question. You are mixing payload elements with headers, for instance. Based on the signature of RestClient.post, which takes arguments url, payload, headers={}, your request should take one of the two following forms:
Is the endpoint expecting named parameters? If so then use the following:
Technique 1: the payload includes a field or parameter named 'upload' and the value is set to the image object
result = RestClient.post(
'http://www.someurl.com/objects',
{ 'upload' => image },
'Accept' => 'application/json',
'Authorization' => 'token',
'Content-Type' => 'image/jpeg',
)
Is the endpoint expecting a simple file upload? If so then use:
Technique 2: the image file object is sent as the sole payload
result = RestClient.post(
'http://www.someurl.com/objects',
image,
'Accept' => 'application/json',
'Authorization' => 'token',
'Content-Type' => 'image/jpeg',
)
Note that I didn't include the 'Content-Length' header; this is not usually required when using RestClient because it inserts it for you when processing files.
There is another way to send payloads with RestClient explained here.
Make sure to read through the official docs on github as well.
I am also new to RestClient so if I'm wrong in this case don't be too harsh; I will correct any misconceptions of mine immediately. Hope this helps!