Laravel and VueJs(Vuetify) Error : MethodNotAllowedHttpException - vuetify.js

Everything working fine before I tried to use Laravel API authentication. And now some GET methods give MethodNotAllowedHttpException and say allowed method are POST,HEAD and for post methods it say allowed methods are GET,Head.
Here is my axios request in my Vue component
axios.post('api/save_post?api_token='+api_token, this.post)
.then(response => {
console.log(this.user);
this.success = response.data.message;
this.post.title=" ";
this.post.content=" ";
})
.catch(err=>{
this.error = err
//this.error = 'Error in saving post, please try again'
});
here is my route in routes/api.php
Route::middleware('auth:api')->post('save_post','Api\KnowledgeHubController#index')->name('savePost');
Included this in my welcome.blade.php file
meta name="csrf-token" content="{{ csrf_token() }}">
before meta there is < so that's not an error.
and Controller function is
public function index(Request $request)
{
$response = KnowledgeHub::create([
"title" => $request['title'],
"content" => $request['content'],
"author_id" => $request['author_id'],
]);
if($response)
{
return response()->json(['message'=>'Post published Successfully','response'=>$response],200);
}
return response()->json(['message'=>'Error in publishing post','response'=>$response],400);
}
some of Solutions I tried
1-included csrf token in header means in my main file(welcome.blade.php)
2-try to pass api_token in different ways to axios.post
3-run php artisan route:cache
Here is the result of php artisan route:list
POST | api/save_post | savePost | App\Http\Controllers\Api\KnowledgeHubController#index | api,auth:api

Can you call the route from outside your vue-application?
If you are 100% that everything is correct:
Try adding the following header to your axios-request:
const headers = {
'Content-Type': 'application/json'
}
axios.post('api/save_post?api_token='+api_token, this.post, headers)
.then(response => {
console.log(this.user);
this.success = response.data.message;
this.post.title=" ";
this.post.content=" ";
})
.catch(err=>{
this.error = err
//this.error = 'Error in saving post, please try again'
});
Still not working?
Try accessing the route with a program like POSTMAN
Clear Laravel Cache
php artisan cache:clear
php artisan route:cache

I resolved this issue but some other error exist.
In exception/handler.php i replace render function to handle error.
public function render($request, Exception $exception)
{
//return parent::render($request, $exception);
if($request->expectsJson())
{
return parent::render($request, $exception);
}else{
return response()->json($exception->getMessage(), 400 );
}
}
and in my router.js file when i remove mode:history
and in my web.php when i comment bellow code which were written to solve the refresh problem of vue component(means when i was refresh on browser it gave me 404 error.)
to solve that problem i used that code at the end of web.php file.
Route::get('{any}', function () {
return view('welcome');
})->where('any','.*');
But now that 404 error problem exist.

Related

laravel8 Undefined variable: errors

I am working on a Laravel Api with Vue js Front end. I have a problem on verify email and reset password. I am sending email using sendGrid In email of reset password button its redirects me to /api/password/reset and this route showing me exception of Undefined variable: errors (View: Path to/ reset.blade.php same is the case with verify email its redirect route is api/email/verify/ which is showing error exception in Undefined variable: errors (View: Path to/login.blade.php.
api.php
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::get('users/send-email', 'App\Http\Controllers\Api\UsersController#sendEMails');
Route::post('client/search', 'App\Http\Controllers\Api\ClientsController#searchBy');
Auth::routes(['verify' => true]);
Route::apiResource('user', 'App\Http\Controllers\Api\UsersController');
Route::apiResource('freelancer', 'App\Http\Controllers\Api\FreelancersController');
Route::apiResource('client', 'App\Http\Controllers\Api\ClientsController');
Route::apiResource('service', 'App\Http\Controllers\Api\ServicesController');
Route::post('service/{id}', 'App\Http\Controllers\Api\ServicesController#update');
Route::post('client/{id}', 'App\Http\Controllers\Api\ClientsController#update');
Route::post('freelancer/{id}', 'App\Http\Controllers\Api\FreelancersController#update');
Route::apiResource('contact_us', 'App\Http\Controllers\Api\ContactUsController');
Route::post('clients/client-referal', 'App\Http\Controllers\Api\ClientsController#findReferal');
Route::post('freelancers/search', 'App\Http\Controllers\Api\FreelancersController#searchBy');
Route::post('services/search', 'App\Http\Controllers\Api\ServicesController#searchBy');
// getting admin users for admin dashboard
Route::get('users/admins', 'App\Http\Controllers\Api\UsersController#getAdminUsers');
Route::apiResource('sales_methods', 'App\Http\Controllers\Api\SalesMethodsController');
Route::apiResource('industries', 'App\Http\Controllers\Api\IndustriesController');
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('user_subscribe_client', 'App\Http\Controllers\Api\SubscribedUserClientsController');
Route::apiResource('apply_job', 'App\Http\Controllers\Api\UserAppliedJobController');
Route::get('users/setup-intent', 'App\Http\Controllers\Api\UsersController#getSetupIntent');
Route::post('users/payments', 'App\Http\Controllers\Api\UsersController#postPaymentMethods');
Route::post('clients/payments', 'App\Http\Controllers\Api\ClientsController#showMyPayments');
Route::get('users/payment-methods', 'App\Http\Controllers\Api\UsersController#getPaymentMethods');
Route::post('users/remove-payment', 'App\Http\Controllers\Api\UsersController#removePaymentMethod');
Route::put('users/subscription', 'App\Http\Controllers\Api\UsersController#updateSubscription');
Route::put('users/update-password/{id?}', 'App\Http\Controllers\Api\UsersController#updatePassword');
Route::post('services/status', 'App\Http\Controllers\Api\ServicesController#changeStatus');
});
**Web.php**
<pre>
Route::middleware('auth')->get('/user', function (Request $request) {
return $request->user();
});
Auth::routes(['verify' => true]);
Route::get('/{any?}', function () {
return view('welcome');
})->where('any', '^(?!api\/)[\/\w\.\,-]*');
Vuejs Password reset form action
async resetPassword() {
const post = { email: this.resetEmail };
const response = await axios
.post("/index.php/api/password/email", post).then((){
further logic
}).catch((){
further logic
})

Laravel Jetstream Route Test With Inertia Returns Error Code 500

Out the test it works, I can visit the page and the controller wroks fine. I wrote the following test:
public function test_logged_user_is_not_redirected()
{
PartnerFactory::new()->create();
$request = $this->actingAs(UserFactory::new()->create())
->get('partners')
->assertRedirect('partners');
dd($request->inertiaProps());
}
I get error code 500. This is the controller:
public function index()
{
return Inertia::render('Partners/Index', [
'filters' => \Illuminate\Support\Facades\Request::all($this->getFilters()),
'contacts' => function() {
return $this->getAllContacts();
}
]);
}
This is the route in web.php
Route::get('partners', [PartnersController::class, 'index'])
->name('partners')
->middleware('auth');
Using refresh database, tried url with a '/' before, I still get 500.
edit: without exception handling i get: Trying to get property 'id' of non-object
Found the solution: The user in jetstream MUST have the personal team!

Laravel 419 Error using Ajax

Okay let me explain first. I am sending a PUT request using ajax like this:
//ajax function
$(document).on("click", ".question_no", function(){
current_color = rgb2hex($(this).css('background-color'));
q_index = $(this).attr('id').slice(5);
id_team_packet = $("#id_team_packet").val();
// startTimer();
if (current_color != '#ffc966') {
$(this).css('background-color', "#ffc966");
var status = "orange";
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: '{{route('peserta.submit.ans.stat')}}',
method: 'put',
data: {q_index, id_team_packet},
success: function(data){
console.log(data)
}
})
}
})
NOTE I already have my CSRF token setup in my head, which I also include in my ajax setup as you can see below. It works great :). But once I protect that route with a Middleware, like this:
//middleware
public function handle($request, Closure $next)
{
if (Auth::user()) {
if (Auth::user()->role == 3) {
return $next($request);
}
if ($request->ajax()) {
return response()->json(['intended_url'=>'/'], 401);
}
return redirect('/');
}
if ($request->ajax()) {
return response()->json(['intended_url'=>'/'], 401);
}
return redirect('/');
}
//web.php
Route::middleware(['participant_only'])->group(function(){
Route::put('/peserta/submit-answer-status', 'PesertaController#submitAnsStat')->name('peserta.submit.ans.stat');
});
As you can see it only accepts logged in user with a role of '3'. If user tries to log in, it redirects to '/'. Now I also check if the request is using ajax, which I return a message with code 401. But unfortunately, when the middleware is applied and I ajax it, it returns this error:
message
exception Symfony\Component\HttpKernel\Exception\HttpException
file -\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php
line 203
But if once I remove the middleware it works. I don't know where the problem is. Oh on another note, If I exclude that particular route from verifycsrftoken it returns the right response both with the middleware and without.
My question is, where is the problem and how do I fix it? Thank you :)

How to prevent an error on undefined routes in Laravel 5.5

I developed an API with Laravel 5.5. All is working fine.
But imagine that a user enter an "api" url directly in the browser (for example: api/books), then they will receive an error:
InvalidArgumentException
Route [login] not defined.
How to prevent this? I tried to add some routes in the routes/web.php file, but without success.
Or perhaps I should do nothing (there will be very few users who will do that)?
I found the answer here:
Laravel 5.5 change unauthenticated login redirect url
I only do that in the "app/Exceptions/Handler.php" file, I modified the function "render" like that :
public function render($request, Exception $exception)
{
// return parent::render($request, $exception);
// add dom
return redirect('/');
// or redirection with a json
/*
return response()->json(
[
'errors' => [
'status' => 401,
'message' => 'Unauthenticated',
]
], 401
);
*/
}
And it works fine. As the "Laravel" part will be used only as back end for APIs, it will be enough.

CSRF Token Duplication on Vue Router Laravel 5.3 Vue 2 JS

So my problems is that the session token is generated.
and the token that i've sent via AJAX or AXIOS (cause im using vue and vue router for fetching API)
is getting a mismatch
This is the response i got when posting data
The ajax token is equal to the token in the meta tag of the main blade template
using this tag
Meta Tag in app.blade.php
<meta name="csrf-token" content="{{ csrf_token() }}">
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
Interceptor of Axios (purpose is to inject the csrf_token from the meta Tag)
Vue.axios.interceptors.request.use(function (config) {
config.headers['X-CSRF-TOKEN'] = Laravel.csrfToken;
console.log(config);
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
Response:
array:1 [
"SessionToken" => "JfhmtCaTiQ49BtF2VK3TysvYnEQSE9n5i1uiHegO"
]
array:1 [
"AjaxToken" => "WqKOiaunbvJbxIsnEjetFoCm1mvdUYESRqfXO2lv"
]
VerifyCSRFToken middleware method:
protected function tokensMatch($request)
{
$sessionToken = $request->session()->token();
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
dd(['SessionToken' => $sessionToken],['AjaxToken' => $token]);
if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
$token = $this->encrypter->decrypt($header);
}
if (! is_string($sessionToken) || ! is_string($token)) {
return false;
}
return hash_equals($sessionToken, $token);
}
So i came up with this idea but its not working because its the token that im getting from the api is null or empty
Here is the method from my RegisterComponent.vue
submitForm() {
this.axios.get('/token')
.then(response => {
this._token = response.data
this.axios.post('/register',this.data)
.then(responseNew => {
console.log(responseNew.data);
})
.catch(responseNew => {
this.errors = responseNew.data;
})
});
}
as you can see im getting a token from my api.php in routes folder
and im also using the authentication api of Laravel and put it on the api routes too
Here is the api.php
Route::group(['middleware' => 'web'], function() {
Auth::routes();
});
Route::get('/token',function() {
dd(csrf_field());
});
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:api');
Route::resource('/users','UserController');
Route::group(['middleware' => 'auth'], function () {
Route::resource('/stores','StoreController');
Route::resource('/items','ItemController');
Route::resource('/transactions','StoreController');
Route::resource('/managers','ManagerController');
Route::resource('/employees','EmployeeController');
Route::resource('/customers','CustomerController');
Route::resource('/tags','TagController');
});
So how can i prevent it from generating that token that will cause mismatch?
Anyone answering this will surely help the authentication of my SPA ( Single Page App)
and its also giving me response status 302
You seem to have a bit misunderstanding. You have the csrf token configured for axios, so every request will have a header field containing the token, then you just need to make sure every request goes through laravel's csrf token validation function before it reaches your business logic, that's all you need to do to prevent csrf. The get('/token') before post('/register') seems unnecessary.
Also, talking about the /token route itself, csrf_field is not appropriate here, since it generates a hidden form field (another way to send csrf token apart from what we talked about earlier) to be embedded in a .php file like <form>...<?=csrf_field()?>...</form> => <form>...<input type="hidden" name="laravel_csrf_token" value="***">...</form>, which makes it meaningless to request csrf_field's result via xhr.

Resources