Laravel - CSRF Token Mismatch - Header Token gets regenerated - laravel

I'm struggeling the last 2 weeks on the following problem:
First of all my problem only occours when I try to deploy my current Laravel (6.11) project on the live server. On my Localhost everything works fine.
In every FORM I used the #csrf tag to set the token as well as the meta tag in the head section of my page. If I search into the developer tool in Chrome the tokens in head and form match perfectly. When the POST request gets sent I get an 419 Page Expired error. I figured out that the HEAD token gets recreated on each request so a token mismatch occours.
I already tried the following things:
Diffrent syntax of the csrf tag
I excepted all FORMS in the VerifyCsrfToken.php - these ended up in a redirect to my index.php without submited form
I checked all Laravel config settings which were recommended in diffrent Forum Posts
I tried a empty laravel installation with a basic login setup on my server - This worked
I currently work with git. On the a previous commit version (16th of december) which I uploaded to my server on that exact Date I had no problem at all but when I tried to reupload the exact same git commit date, the same problem happens.
Greatings Max
If you need any code I'll upload here.
Controller:
function fakeAuthentifizierung(Request $request){
$username = $request->input('benutzernameLogin');
$password = $request->input('passwortLogin');
session(['key' => 'mt171043']);
session(['eingeloggt' => true]);
/*****
* ABFRAGE ADMINRECHTE
* BITTE DIESEN TEIL SPÄTER IN ECHTE AUTHENTIFIZIERUNG ÜBERNEHMEN
*
*/
$admin = false;
// SPÄTER BENUTZERID AUS LOGIN SESSION ÜBERGEBEN
// astmedin5 als TESTZWECK
$rechte = Benutzer::getBenutzerBerechtigung("astmedin5");
//Berechtigung Abfragen
if($rechte->name != 'Student' && 'Lehrbeauftragter'){
session(['admin' => true]);
}else{
session(['admin' => false]);
}
/***
*
* ABFRAGE ENDE
*/
return redirect(route('index',app()->getlocale()));
}
View:
<form method="POST" action="{{ action('LoginController#FakeAuthentifizierung', app()->getLocale()) }}">
#csrf
<h1>{{ __('Login') }}</h1>
<label class="col" for="benutzernameLogin">{{ __('Benutzername') }}</label>
<input name="benutzernameLogin" id="benutzernameLogin" class="inputLogin col mb-4" type="text"
aria-label="Text input with checkbox" placeholder="{{ __('Benutzername') }}" required>
<label class="col" for="passwortLogin">{{ __('Passwort') }}</label>
<input name="passwortLogin" id="passwortLogin" class="inputLogin col mb-4" type="password"
aria-label="Text input with checkbox" placeholder="{{ __('Passwort') }}" required>
<div class="col-8 float-left">
<input id="checkboxPasswortAnzeigen" type="checkbox">
<label for="checkboxPasswortAnzeigen">{{ __('Passwort anzeigen') }}</label>
</div>
<button type="submit" class="btn-slash col-3 inverted fontLight float-right">{{ __('Login') }}</button>
</form>

Related

The POST method is not supported for this route. Supported methods: GET, HEAD. + Laravel

I am trying to update .
I am getting the error
The POST method is not supported for this route. Supported methods: GET, HEAD.
Following are the code
In Route
Route::post('editcountries','App\Http\Controllers\backend\admineditcountryController#editcountries');
In Controller
function editcountries(Request $request)
{
$country_en = $request->input('country_en');
$country_ar = $request->input('country_ar');
$id = $request->input('idd');
$cstatus = 1;
if (isset($request->status))
$cstatus = 1;
else
$cstatus = 0;
$isUpdateSuccess = country::where('id',$id)->update(['country_en'=> $country_en,
'country_ar'=> $country_ar,
'status' => $cstatus
]);
$this->clearToastr();
session()->put('updated','Information updated Successfully.');
return view('backend.adminaddcountry');
}
In blade
<form action="editcountries" method="POST" enctype="multipart/form-data">
#csrf
{{-- #method('PUT') --}}
{{-- <input type="hidden" name="_method" value="PUT">" --}}
<div class="input-style-1">
<label>Country Name in English </label>
<input type="text" name="country_en" placeholder="Country Name in English"
value='{{ $clist->country_en }}' required/>
</div>
<div class="input-style-1">
<label>Country Name in Arabic</label>
<input type="text" dir="rtl" name="country_ar" placeholder="اسم الدولة بالعربية" value='{{ $clist->country_ar }}' />
</div>
<!-- end input -->
<div class="form-check form-switch toggle-switch">
<input class="form-check-input" name="status" type="checkbox" id="toggleSwitch2" #if($clist->status==1)
checked=""
#else
#endif>
<label class="form-check-label" for="toggleSwitch2">Enable or disable the country.</label>
</div>
<input type="hidden" id="idd" name="idd" value="{{ $clist->id }}" />
<br>
<button class="main-btn primary-btn btn-hover text-center">Update</button>
</form>
I tried using
#method('PUT')
but then getting error
The PUT method is not supported for this route. Supported methods: GET, HEAD.
Please help
I tried putting
I tried using
#method('PUT')
but then getting error
The PUT method is not supported for this route. Supported methods: GET, HEAD.
Please help
You might have your routes cached, you can try running the following commands in the terminal:
php artisan route:clear
php artisan route:cache
You should get rid of the code you added making it a put request, unless that is what you want. If you want it to be a PUT route you need to use:
Route::put
Otherwise if you still can't figure it out, go through your routes file and check for any other routes that match "editcountries". Sometimes the order you put the routes can cause conflicts with other routes, like a resource route for example. However I would say if you get rid of the PUT code in the blade file, and run the route cache commands I provided, you should have it working with the post route.
How to Debug:
Run: php artisan route::list --path admineditcountryController
If you do not see your controller in the output run php artisan route:clear
I would not recommend running route:cache as you'll have to continuously route:clear any time you change/add/remove routes — set that up in your CI to only run in PROD. In fact — you should just run php artisan optimize in production and it'll do a bunch of fancy performance Laravel magic for ya (further reading)
Other Improvements (PR Comments)
1. Follow PSR-2 File/Class/Namespace NAming
Aside, make sure your folder & namespaces are following PSR-2 (CamelCase)
App\Http\Controllers\backend\admineditcountryController
# should be
App\Http\Controllers\Backend\AdminEditCountryController
# even better (Namespaced)
App\Http\Controllers\Backend\Admin\CountryController
2. Reference controllers using an import
This is a bit cleaner (PHP 7+) + try utilizing Route::resource + Laravel Action Verbs as controller function names docs
use App\Http\Controllers\Backend\AdminEditCountryController;
/* Simplified - Best practice: use dashes as URL delimiters '-' */
Route::post('edit-countries', AdminEditCountryController::class . '#editcountries');
/* PRO VERSION */
Route::group('admin')->prefix('admin')->name('admin.')->group( function () {
// AdminEditCountryController#update()
Route::resource('country', Admin\CountryController::class)->only(['update']);
});
3. Extra Credit
Try generating your controllers (benefits from PSR-2 compliant namespace & folder layouts):
php artisan make:controller Admin\CountryController --resource
I resolved it.
Route
Route::post('/editcountries','App\Http\Controllers\backend\admineditcountryController#editcountries');
Controller
function editcountries(Request $request)
{
$country_en = $request->input('country_en');
$country_ar = $request->input('country_ar');
$id = $request->input('idd');
$cstatus = 1;
if (isset($request->status))
$cstatus = 1;
else
$cstatus = 0;
$isUpdateSuccess = country::where('id',$id)->update(['country_en'=> $country_en,
'country_ar'=> $country_ar,
'status' => $cstatus
]);
$this->clearToastr();
session()->put('updated','Information updated Successfully.');
$data = country::where('id', '=', $id)->first();
return view('backend.admineditcountry',['clist'=>$data]);
}
Blade
<form action="/editcountries" method="POST" enctype="multipart/form-data">
#csrf
<div class="input-style-1">
<label>Country Name in English </label>
<input type="text" name="country_en" placeholder="Country Name in English"
value='{{ $clist->country_en }}' required/>
</div>
<div class="input-style-1">
<label>Country Name in Arabic</label>
<input type="text" dir="rtl" name="country_ar" placeholder="اسم الدولة بالعربية" value='{{ $clist->country_ar }}' />
</div>
<!-- end input -->
<div class="form-check form-switch toggle-switch">
<input class="form-check-input" name="status" type="checkbox" id="toggleSwitch2" #if($clist->status==1)
checked=""
#else
#endif>
<label class="form-check-label" for="toggleSwitch2">Enable or disable the country.</label>
</div>
<input type="hidden" id="idd" name="idd" value="{{ $clist->id }}" />
<br>
<button class="main-btn primary-btn btn-hover text-center">Update</button>
</form>

Laravel 8 Livewire and google places autocomplete not working

sI have a livewire form with an address field that has google places autocomplete enabled on it. Every time I select an address from the autocomplete list and move to a new input in the form the address input gets reset to the value before clicking the address I wanted.
I added wire:ignore on my field and it still gets reset to the value typed in before the click event. This is my code for the input:
<div wire:ignore id="for-input-address" class="form-group col-lg-6{{ $errors->has('address') ? ' has-danger' : '' }}">
<label class="form-control-label" for="input-address">{{ __('Home address') }}</label>
<input wire:model="address" type="text" name="address" id="input-address" class="form-control form-control-alternative{{ $errors->has('address') ? ' is-invalid' : '' }}" placeholder="{{ __('Home address') }}" value="{{ old('address') }}" required autofocus>
#if ($errors->has('address'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('address') }}</strong>
</span>
#endif
</div>
So if I type 56 and select the address the moment I move to the next field the input gets reset to 56.
I want to say I have some select fields with wire:ignore that work just fine when livewire reloads the DOM.
Put an additional attribute to your input -> autocomplete="off" to tell the browser not to use any autocomplete mechanisms.
See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
I ended up using livewire events, documented here: https://laravel-livewire.com/docs/2.x/events in my blade file and I fired an event on google autocomplete "place_changed" like so
google.maps.event.addListener(autocomplete, 'place_changed', function() {
Livewire.emit('addressUpdated', addressAndTown, postcode);
});
and in my controller I did the following before the submit function
public function addressUpdated($address, $postcode)
{
$this->address = $address;
$this->postcode = $postcode;
}
and updated my values in the controller

Laravel Post method is not working because of the special characters

I am facing a very abnormal situation here.
Below are the image of simple HTML form, with input type files and text and text area.
<form method="POST" action="{{ route('vendor.package.store') }}" enctype="multipart/form-data">
{!! csrf_field() !!}
<input type="text" class="form-control" id="title" name="package_name" value="{{ old('title')) }}" required>
</form>
When I enter "On-The-Day (OTD) Vacation In Bali Island", and hit "Submit Button", Laravel redirect me to the index page, means the below function does not trigger at all.
public function store(Request $request){
return $request->all();
}
So, I tried to answer enter "(OTD)" & "On-The-Day", Laravel redirect me to the store function
But whenever I tried to enter "On-The-Day (OTD)", fails.
When I try to enter "-Day (OTD)", fails
When I try to enter "-DaZ (OTD)", success.
P/S: my local development can accept On-The-Day (OTD) Vacation In Bali Island, only in production side cannot process the word.
Appreciate if you could help

Getting a Forbidden when trying to access my controller

I've created a form that when submitted it needs to go to a controller function.
At the moment when I'm submitting my form I keep getting
Forbidden
You don't have permission to access /client_area/shop/payment-gateway on this server.
Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.
I've done forms before but this is the first time this has happened to me and it has me stumped.
my form
<div class="payment-form">
<form action="{{ route('payment.gateway') }}" method="POST">
#csrf
<input type="hidden" name="return_url" value="{{ route('payment.success') }}">
<input type="hidden" name="cancel_url" value="{{ route('payment.cancel') }}">
<input type="hidden" name="m_payment_id" value="{{ $invoice_number }}">
<input type="hidden" name="amount" class="completePrice" value="">
<input type="hidden" name="item_name" value="Test Item">
<input type="hidden" name="item_description" value="A test product">
<input type="hidden" name="delivery_collection" class="delivery_collection" value="">
<input type="hidden" name="delivery_fee" class="delivery_fee" value="{{ $delivery }}">
<input type="hidden" name="delivery_address" class="delivery_address" value="{{ $address }}">
<button type="submit" class="btn btn-success float-right confirm-order">
Confirm Order
</button>
</form>
</div>
my routes
Route::group(['middleware' => ['web', 'auth']], function(){
Route::get('/account/dashboard', 'UsersController#accountDashboard')->name('account.dashboard');
Route::get('/account/details', 'UsersController#personalDetails')->name('account.details');
Route::get('/account/track-orders', 'UsersController#trackOrders')->name('account.track-orders');
Route::get('/account/invoices', 'UsersController#invoices')->name('account.invoices');
Route::get('/account/address', 'UsersController#addressesIndex')->name('account.addresses.index');
Route::get('/account/sort-orders', 'UsersController#sortOrders')->name('account.sort-orders');
Route::get('/account/order-details/{invoice_number}', 'UsersController#orderDetails')->name('account.order-details');
Route::get('/account/invoice-pdf/{id}', 'UsersController#invoicesPdf')->name('account.invoices.pdf');
Route::get('/account/create-address', 'UsersController#createAddress')->name('account.create.address');
Route::get('/account/edit-address/{id}', 'UsersController#editAddress')->name('account.edit.address');
Route::get('/delivery-confirmation', 'PublicController#deliveryConfirmation')->name('cart.deliveryConfirmation');
Route::get('/account/edit-delivery-address/{id}', 'UsersController#editDeliveryAddress')->name('account.edit.delivery.address');
Route::get('/payment-success', 'PublicController#successPayment')->name('payment.success');
Route::get('/payment-cancel', 'PublicController#cancelPayment')->name('payment.cancel');
Route::post('/account/personal-details', 'UsersController#postPersonalDetails')->name('post.personal-details');
Route::post('/account/business-details', 'UsersController#postBusinessDetails')->name('post.business-details');
Route::post('/account/addresses-radio/{id}', 'UsersController#postAddressesRadio')->name('account.post.addresses.radio');
Route::post('/account/create-address', 'UsersController#postAddress')->name('account.post.address');
Route::post('/account/edit-address/{id}', 'UsersController#updateAddress')->name('account.update.address');
Route::post('/payment-gateway', 'PublicController#paymentGateway')->name('payment.gateway');
Route::delete('/account/delete-delivery-address/{id}', 'UsersController#deleteDeliveryAddress')->name('account.delete.delivery.address');
});
I've only done a dd() to make sure I hit the right function
public function paymentGateway()
{
dd('this is a payment gateway');
}
My Auth Middleware
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* #param \Illuminate\Http\Request $request
* #return string
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
}
This is what I see when I go through the network tab. Because it's alot of images I thought it would be better to have it as a link then just pasting the images here.
Image 1
Image 2
Image 3
Image 4
Image 5
Image 6
Image 7
Image 8
Laravel comes with Cross Site Request Forgery protection. You need to also pass a field named csrf-token as stated here in the documentation.
https://laravel.com/docs/5.8/csrf#csrf-x-csrf-token
If you do not want this protection you must include the route in the VerifyCsrfToken Middleware to exclude the checking.
https://laravel.com/docs/5.8/csrf#csrf-excluding-uris
Try this to see if that solves your issue.

different dates from different views to be displayed in a database in laravel

I am creating a website that allows books to be loaned out, i have 3 options for the loans which are 1 week, 2 weeks and 4 weeks,when a user clicks a book they will be taken to a details page that will display the 3 loan options, if you click on the 1 week loan you will be taken the one week loan page where you can confirm or cancel the loan, the page looks like this
<?php
use Carbon\Carbon;
?>
#extends('layouts.app')
#section('content')
<div class="container">
<div class="panel panel-default">
<div class="panel-heading"><h1>1 Week Loan</h1></div>
<div class="panel-body">
<h4>You have attempted to loan out: </h4>
<h4>{{$book->title}}</h4>
<h4>By: {{$book->author}}</h4>
<br/>
<h4>To agree, press the confirm button, to cancel the loan press the cancel button and you will be returned to the home screen.</h4>
<br/>
<form action="{{url('loan')}}" method="POST">
{{ csrf_field() }}
<input type="hidden" name="l_userid" value="{{ Auth::user()->userid }}" id="l_userid">
<input type="hidden" name="l_f_name" value="{{ Auth::user()->f_name }}" id="l_f_name">
<input type="hidden" name="l_l_name" value="{{ Auth::user()->l_name }}" id="l_l_name">
<input type="hidden" name="l_bookid" value="{{$book->bookid}}" id="l_bookid">
<input type="hidden" name="l_title" value="{{$book->title}}" id="l_title">
<input type="hidden" name="ddate" value="" id="ddate">
<input type="submit" name="requaestbtn" value="Confirm">
</form>
<a href="{{url('home')}}" class="btn btn-primary" role="button">
Cancel</a>
</div>
</div>
#endsection
on each loan page there will be the hidden input types that will send the data to the controller but i want the 'ddate' hidden input to have the value of 1 week from now if the user is on the 1 week loan page, 2 weeks from now if they are on the 2 week loan page etc.,
this is the function i have in my controller:
public function loan(Request $request)
{
$loan = new Loan();
$loan->userid = $request->l_userid;
$loan->f_name = $request->l_f_name;
$loan->l_name = $request->l_l_name;
$loan->bookid = $request->l_bookid;
$loan->title = $request->l_title;
$loan->startdate = Carbon::now();
$loan->duedate = $request->ddate
$loan->save();
return view('home');
}
Ok the solution to your question is that you can set the value to a number corresponding to the number of weeks of loan period. In your case the values are 1, 2 and 4. Then in the controller you can generate a date based on the loan period number you've received.
But at the same time i have to warn you about the bad practises you're following. Your form can be edited by the user to loan a book as another person. Never send the user information in the form, it can be edited by the end user. Instead use the currently logged in user's info in the controller directly.
<form action="{{url('loan')}}" method="POST">
{{ csrf_field() }}
<input type="hidden" name="l_bookid" value="{{$book->bookid}}" id="l_bookid">
<input type="hidden" name="l_title" value="{{$book->title}}" id="l_title">
<input type="hidden" name="ddate" value="1" id="ddate">
<input type="submit" name="requaestbtn" value="Confirm">
</form>
public function loan(Request $request)
{
$loanWeeks = min($request->ddate, 4);
$loan = new Loan();
$loan->userid = auth()->user()->userid;
$loan->f_name = auth()->user()->f_name;
$loan->l_name = auth()->user()->l_name;
$loan->bookid = $request->l_bookid;
$loan->title = $request->l_title;
$loan->startdate = Carbon::now();
$loan->duedate = Carbon::now()->addWeeks($loanWeeks);
$loan->save();
return view('home');
}
I've also added a small check to make sure the user can only lease the book for maximum of 4 weeks. If you don't add this check then the end user can again edit the value and loan the books for however long they want.
Can you just put in the view:
<input type="hidden" name="ddate" value="1" id="ddate">
and then in the controller:
$loan->duedate = Carbon::now()->addWeeks($request->ddate);

Resources