Rapid API, Google Translate post request with laravel - laravel

I need to use the Google Translate API in my Laravel application, get requests are working fine, but post requests don't seem to, I tried with Postman and got the same error message.
Here's the test I made:
Route::get('/', function () {
return Http::withHeaders([
"content-type" => "application/x-www-form-urlencoded",
"accept-encoding"=> "application/gzip",
"x-rapidapi-key"=> "<rapid_api_key_here>",
"x-rapidapi-host"=> "google-translate1.p.rapidapi.com",
"useQueryString"=> true
])->post('https://google-translate1.p.rapidapi.com/language/translate/v2/detect', [
"q"=> "English is hard, but detectably so",
]);
});
Here's the test with Postman:
Here's the error I got in both tests:
I don't know what went wrong, any suggestions?

You can try using Route::post method instead of get as you're making a post request here.
Context: https://laravel.com/docs/5.0/routing#basic-routing

Related

Laravel HTTP Client Bad Request on Discord API Access Token Exchange

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);

Laravel API request middleware unathenthicated

I need your help with my Laravel API HTTP Request. I am trying to get a response from my api. But it sends back "Error: "Request failed with status code 401" and the AuthenthicationException shows "Unauthenticated." . I have not found any solutions. I need your help... Thanks.
const response = (await rootApi.get(`/openSesame/targets/${id}`)).data;
My 'Api\TargetController
public function detail($id)
{
$spintaxInput = SpintaxInput::find($id);
if (!$spintaxInput) {
return response()->json(['error' => "Not found."], 404);
}
return response()->json($spintaxInput, 200);
}
My api routes
Route::group(['middleware' => ['auth:web']], function () {
Route::group(['prefix' => 'openSesame'], function () {
Route::get('/targets/{id}', 'Api\TargetController#detail');
});
});
you should use Sanctum to API authenticate
Passport would be the way to go here.
check Passport
Now, to help you with this:
To be able to authenticate when you're going to make a request to the api, make sure to use the header: Authentication and the token followed by Bearer
A token example should be like this one:
Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiZThmNjZiMTU0Yjg4OGM2YmI2ODg0ZDM2ZDU3NGYxY2FiODFjODgyMmI0MDc5NDVkMTNjM2I2MDdiMDc0MGNkNTI1MzgxZDU2NWJkNWUwZTciLCJpYXQiOjE1ODY3MDY1MzgsIm5iZiI6MTU4NjcwNjUzOCwiZXhwIjoxNjE4MjQyNTM4LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.Brf48KrE3smifCIo61_8alvU8Yi5atsMtLz5t7-drQ7xnpG0Lga9q7Wh8RDJaYLtxHltdMLRVfp2HtstVQO6XY8qE0GNqS2pfjwFGDJTChWDSbINzjRyX9rO9FdTbE95TPlh84e_PRQ7iWMDO_DQkB67YvuYieXJjWAzF5UBGjK9ZMSjjzHahHV-iCE4Si_i0DHP6bLDTksZd51jiYV7ptGr41lZCwnL09fNjtWtLYTl79OoxIzcEPZMUQ_l7QcoJPJUYa0-lvHAta9hbkzZHdskIOB9C6afel4VxPFEVI0RmP5glJBJFKu0A_0N80iJf7yhXqofk5muF-bFWv9_092os2h3-zt0bDjTb7jeSAY8CkgxRQ3oLtRQN9MBgxRdUechycdimbKpU6hhpGfJfsofHtJiRGAbh5Eddlq5AGjdZkRW6zu9CjFUFiivZHOO_JI3HmU39jXUQx8218Czb9_Z-iG02K0Bvtk0eilvZl3k6FjvDka3beb0Zg99Da5MKeYSMKXqn4U-mndQPPtsidWCwh4foskzv6mRvWhsGh8xN0zByCTIhML-ogqrIGNcDUsrgpi2E4eue4PZ9DfYIa740kYKnJLzpNC6_ilQPesb3MjqLLx9DBcUkuWH7fwKKA_OaxhIv2WiELUECjWuIIDMpNGuK_Kes0RbqedPvlg
When using API's, you will need to use that header in each request. Otherwise you will get a 401. The 401 means that you're not logged in.
You should use passport, like said.
And for auth middleware, replace it to:
middleware('auth:api')

"The GET method is not supported for this route. Supported methods: POST" message in my laravel API

I followed a tutorial to do a login page with an external api, but my API is not working.
In the localhost http://localhost:8000/api/auth/login appear "The GET method is not supported for this route. Supported methods: POST." and in the Chrome DevTools
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure response for http://127.0.0.1:8000/api/auth/register: 422 Unprocessable Entity"
name: "HttpErrorResponse"
ok: false
status: 422
statusText: "Unprocessable Entity"
url: "http://127.0.0.1:8000/api/auth/register"
I use laravel 6,php 7, ionic 4
Please, help me!
(tutorial is: https://blog.flicher.net/laravel-rest-api-passport-authentication-for-ionic-app/)
If you follow the tutorial in section Step 6 — Set API routes it list down all routes for api.
Here it says as below
File: api.php
Route::group([
'prefix' => 'auth'
], function () {
Route::post('login', 'Auth\AuthController#login')->name('login');
});
That means we have a route with name as login which would be a POST request and url would be api/auth/login as it is api.php file.
You are calling it from the browser, that would be a get request, which is not found by laravel in routes, so it is generating this error.
Reference: Laravel Routing

Axios/XMLHttpRequest is sending GET instead of POST in production environment

I am running into a very strange issue. We are putting an app into production and one of the POST request is turning into a POST followed directly by a GET request to the same URL and the POST is never received in the backend (Laravel). In the chrome network tab it just looks like just a GET but with Burpsuite we can see the POST request.
The code responsible
async store() {
// This prints post
console.log(this.method());
await this.form[this.method()]('/api/admin/users/' + (this.isUpdate() ? this.id : ''));
if (!this.isUpdate()) {
this.form.reset();
}
},
The form.post method content
return new Promise((resolve, reject) => {
axios[requestType](url, this.data())
.then(response => {
this.busy = false;
this.onSuccess(response.data);
resolve(response.data);
})
.catch(error => {
this.busy = false;
if (error.response.status == 400) {
return this.displayErrors(error.response.data)
}
this.onFail(error.response.data.errors);
reject(error.response.data);
});
});
This question was also answered by me in the Larachat slack forum, and for others sake here is the answer for the next one with such a problem.
Just a little back story. In the chat we found out that it was receiving a 301 error which is a redirect error.
I had the same error recently when posting to a url on a staging server, it was working fine locally but not on the staging server.
The problem appeared to be a slash at the end of the post url.
So posting to https://example.com/post/to/ will not work.
Removing the / and posting to https://example.com/post/to will work.
Just for info, I had the same thing - axios request was being redirected. For me though, it turned out to be some localization middleware causing the redirect!
I set up an alternative route in the Api routes file (again Laravel as in the question), bypassing that middleware (probably where the route should have gone in the first place!). All good now! Schoolboy error I guess!
I confirm the previous answer. And I had the same problem from local to production ambience.
The call to an endpoint like / api / user / store / might be redirect to / api / user / store with a 301 status code and this call was interpreted like a GET that obviously we cant reach (because it not in our route list). So it don't work.
A solution can be to work on Apache configuration (trim last slash) but I prefer to adapt my Axios call.

How to retrieve JSON from a API endpoint using Laravel 5.4?

I have 2 projects made with Laravel 5.4:
Prj-1 it is an Restful API that returns JSON.
Prj-2 it is an website that consumes the above endpoints.
In this way, I have the follow endpoint from Prj-1 :
myAPI.com/city that returns a list of all cities in the database in a JSON format.
Inside Prj-2 I have the follow:
Route:
Route::get('/showCityAPItest','AddressController#getcity');
Controller:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
...
public function getcity()
{
$request =Request::create('http://myAPI.com/city', 'GET');
$response = Route::dispatch($request);
dd($response);
}
If I use directly the URL (http://myAPI.com/city) in the browser, it works. I can see the JSON as expected.
BUt when I try to retrieve it from the Prj-2 I can't see it in the browser.
Actually I see
404 Not Found
nginx/1.10.1 (Ubuntu)
I was following this post but I dont know what am I doing wrong.
Any help?
Yeah, #Joel Hinz is right. Request will work within same project api end.
You need to use GuzzleHttp.
Step 1. Install guzzle using composer. Windows base operating guzzle command for composer :
composer require guzzlehttp/guzzle
step 2 write following code
public function getcity()
{
$client = new \GuzzleHttp\Client;
$data =$client->request('GET', 'http://myAPI.com/city', [
'headers' => [
'Accept' => 'application/json',
'Content-type' => 'application/json'
]
]);
$x = json_decode($data->getBody()->getContents());
return response()->json(['msg' => $x], 200);
}
The answer to which you are referring is talking about internal routes. You can't use the Request and Route facades for external addresses like that. Instead, use e.g. Guzzle (http://docs.guzzlephp.org/en/latest/) to send your requests from the second site.

Resources