Laravel: Send HTTP request to own API with headers - laravel

I want to consume my own API (with authentification) for my website which is on the same domain. For instance, if the user of the website wants to see the list of the posts:
1. He goes to mywebsite/posts, thus making a GET /mywebsite/posts request.
2. The web app dispatches the request and calls the listPosts() function of the WebsiteController.
3. The listPosts() function creates a new request to the API like that:
$token = 'd0aE73j...';
$request = Request::create('/api/posts', 'GET', [], [], [], [
'Authorization' => 'Bearer '.$token, //The header for authentification
'Accept' => 'application/json', //The header supposed to prevent the error below
], []);
$response = Route::dispatch($request);
4. The JSON result of the request is passed and displayed in the view of the list of posts:
return view('mywebsite.listposts')->with('listPosts',$response);
The problem I have is at 3., the request returns an error:
InvalidArgumentException: Route [login] not defined. in file C:[...]\vendor\laravel\framework\src\Illuminate\Routing\UrlGenerator.php on line 370
What I want to know is:
1) How to make a proper HTTP request with headers to my own API,
2) How to return a JSON instead of this error when the Accept: application/json is not present.
Thank you for your help.

Related

Make a post request to a api that uses sanctum via Client (Laravel-6.2)

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!

i have token in header of ajax and when i get dd return null

i wanna send GET request from frontend to backend
i mean i want to send token from frontend to middlware
i mean i want get token from cookie and push in GET request and send for one of route in api.php that the route is GET method
i mean i want to push my token in ajax and send to laravel
infact i have two laravel project that i want send token from one to another
i mean i want push my token in header in ajax and get in backend with laravel
so see my code in the below fisrt my route from backend
later my jquery and then middleware
but my current problem is that when i dd header is is null
thanks
Route::get('/customers', 'App\Http\Controllers\CustomerController#show');
//
$.ajax({
url: "http://localhost:8000/api/customers",
type: "GET",
headers: {
"Authorization": getCookie("access_token")
}
});
//
dd($request->header('Authorization'));
if ($request->hasHeader('Authorization')) {
$access_token = $request->header('Authorization');
$query = DB::table("admins")->where("access_token", $access_token)->first();
if (isset($access_token) && $access_token == $query->access_token) {
return $next($request);
} else {
return response()->json([
"status" => 401,
"message" => "شما اجازه دسترسی ندارید",
]);
}
}

Laravel API not accepting JSON request from Postman

Laravel API is not accepting JSON request. If I request as form-data it works but if I post JSON object in postman body then it does not receive the request data.
Route:
$router->group(['prefix' => 'imp'], function () use ($router) {
$router->group(['prefix' => 'lead'], function () use ($router) {
$router->post('/jardy', 'FeedController#jardy');
});
});
Controller:
public function jardy(Request $request)
{
$this->validate($request, [
'api_key' => 'required',
]);
$api_key = $request->input('api_key');
return $api_key;
}
JSON Request:
Form data Request:
Why its not working in case of JSON, content-type is application/json, Accept:*/*???
Comments are not permitted in JSON.
There's a bug in the field Body -> raw -> json
You have to add the header
Accept: application/json
Then laravel parses your RAW json as input vars and they can be accesed with ->input()
see:
using / which is the postman default, will not work..
If you dont want to relay on the header, you could also do $request->json() but i guess, you just want to pass the header.
See the source that handles this:
https://github.com/laravel/framework/blob/7.x/src/Illuminate/Http/Concerns/InteractsWithContentTypes.php#L52
and
https://github.com/laravel/framework/blob/7.x/src/Illuminate/Http/Concerns/InteractsWithContentTypes.php#L32
In my case it was lack of Content-Length header.
Value should be a number of characters of request body.
Content-Type: application/json also should be present.

Axios AJAX call nulls parameter

I use Vuejs to create my frontend for my project.
At the creation of one component ('TimeCapsy.vue'), I make an AJAX call to my backend like this:
created: function () {
if (verify.verify_login()) {
let token = this.$cookies.get('jwt_us_cas');
let params = {'jwt': token};
console.log(params);
axios({
method: 'post',
url: dev.HOST+'getuserinfoobject',
params: queryString.stringify(params)
})
.then(response => {
console.log(response.data)
})
}
}
As you can see I use the
this.$cookies.get('jwt_us_cas');
to get the a json web token, that I set on the client at the login.
I use the queryString Library to stringify my parameters for my request.
I also tried it without the queryString.stringify(params) call, but I get the same error, e.g. the parameter still turns into null.
When I look at the console log, where I check the params variable, I get this output:
{jwt: "my token comes here"}
So I can see, that it gets the correct value from the cookie.
But when I check the answer from my backend (PHP), I get this error:
Undefined index: jwt in <b>D:\casb\public\index.php</b> on line <b>52</b>
Of course I know that it means, that jwt is null, but I can't understand why.
As I said, right before I make the call I check the params and it shows the token.
I checked the endpoint with Postman and the token as the jwt parameter and it returned a successfull call with the correct answer.
A correct answer is basically just a nested object with some information in it.
My PHP endpoint is pretty basic too:
Router::add('/getuserinfoobject', function () {
$response['response'] = User::getUserInfoObject($_POST['jwt']);
echo json_encode($response);
}, 'post');
So I guess that right before or in my call it nulls my parameter. But I can't understand how, since I make a lot of requests and never had this problem.
From axios docs
params are the URL parameters to be sent with the request
Which means, you should get the value with PHP $_GET.
Or $_REQUEST (which stores both $_GET, $_POST. Also $_COOKIE).
The other hand, you can use data key as docs says
data is the data to be sent as the request body
Only applicable for request methods PUT, POST, and PATCH
So the value would be available in $_POST
axios({
method: 'post',
url: dev.HOST+'getuserinfoobject',
data: {
jwt: token
}
})

Yii2 CORS inserts two records

I am building an API with Yii2 and have enabled the CORS filter to handle requests from a web frontend which is working.
However because of the pre-flight OPTIONS request and then the real POST request I am getting two records added to the database, one for each request. I would have thought that Yii should accept the OPTIONS request, return the correct headers and then exit. Why does it actually process the full request?
I am working around this for now by adding this to the top of the controller action:
if(Yii::$app->request->getMethod() == 'OPTIONS') {
return;
}
Is that the best approach or am I missing something?
That should be wrong because a browser need the options response to know the allowed list of verbs he can send. Otherwise a 401 error may be raised. Its source code can be seen here:
class OptionsAction extends \yii\base\Action
{
public $collectionOptions = ['GET', 'POST', 'HEAD', 'OPTIONS'];
public $resourceOptions = ['GET', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'];
public function run($id = null)
{
if (Yii::$app->getRequest()->getMethod() !== 'OPTIONS') {
Yii::$app->getResponse()->setStatusCode(405);
}
$options = $id === null ? $this->collectionOptions : $this->resourceOptions;
Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', $options));
}
}
And that is all what it does: sending a list of allowed verbs within a response headers.
Maybe the POST request has been sent twice from client script due to unexpected responses. Try to apply the answer I posted in your other question instead. I think it will also solve this:
Yii2 CORS with Auth not working for non CRUD actions.

Resources