403 Forbidden after using #csrf in laravel 8 form - php

I am new to programming especially laravel. I am trying to make a CRUD and have already added example data in prequel (using Docker). I can see the data, but when I´m trying to create new posts with a form I get Code 419 page expired. I know that´s normal and the solution is to add #csrf to the form. But after doing this I get 403 Forbidden. I tried a lot but can´t find a solution to fix it.
I would be really happy if someone could help me fix my problem.
Here is my create.blade.php
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-header">{{ __('Alle Gerichte') }}</div>
<div class="card-body">
<form action = "/recipe" method="POST">
#csrf
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name">
</div>
<div class="form-group">
<label for="beschreibung">Beschreibung</label>
<textarea class="form-control" id="beschreibung" name="beschreibung" rows="5"></textarea>
</div>
<input class="btn btn-primary mt-4" type="submit" value="absenden">
</form>
<a class="btn btn-primary btn-sm mt-3 float-right" href="/recipe"><i class="fas fa-circle-up"></i>Zurück</a>
</div>
</div>
</div>
</div>
</div>
#endsection

hi is that you have created validation rules
in StoreRecipeRequest
do that
public function authorize()
{
return true;
}

Controller Code will be like this:
public function store(StoreRecipeRequest $request)
{
//dd($request);
$recipe = new Recipe( [
'name' => $request->name,
'beschreibung' => $request->beschreibung,
]);
$recipe->save();
return redirect('/recipe');
}
Also if it's not solved. Then let's try it.
public function store(StoreRecipeRequest $request)
{
$recipe = new Recipe();
$recipe->name = $request->name;
$recipe->beschreibung = $request->beschreibung;
$recipe->save();
return redirect('/recipe');
}
also, can you add in your Recipe Model?
protected $fillable = [
'name',
'beschreibung',
];

Related

Update not working in Resource Controller for Laravel 8

Previously, I was trying for a few hours to get my "destroy()" function working. Which would sound ridiculous to most of you but simply putting "method("DELETE")" in the form made it work, which I still don't why.
Now, I'm stuck with the update() function. Once I click update, the page just reloads and does nothing. It doesn't update the info in the database nor does it redirect me back to the index. Here's the code:
Route (web.php):
Route::resource('books', BookController::class);
Form (Edit.blade.php):
#section('content')
<div class="row">
<div class="col-lg-12">
<form action="{{ route('books.update', $book->id) }}" method="POST">
#csrf
#method('PUT')
<div class="mb-3 mt-3">
<label for="exampleFormControlInput1" class="form-label">Book Title</label>
<input type="text" name="title" class="form-control" value="{{ $book->title }}">
</div>
<div class="mb-3">
<label for="exampleFormControlTextarea1" class="form-label">Book Author</label>
<input type="text" name="author" class="form-control" value="{{ $book->author }}" placeholder="Author Name..">
</div>
<div class="btn-group" role="group">
<button type="submit" class="btn btn-block btn-danger">Update</button>
<button type="button" class="btn btn-success">Go Back</button>
</div>
</form>
</div>
</div>
#endsection
Controller (BookController):
public function update(Request $request, Book $book)
{
$validated = $request->validate([
'title' => 'required|max:255|unique:books',
'author' => 'required|max:255'
]);
Book::where('id',$book->id)->update($validated);
return redirect()->route('books.index')->with('message','Book Updated!');
}
What am I doing wrong here? Some help would be appreciated.
I think the problem is in your unique validation. When you don't change the title in the form and hit updated, the unique validation fails. It fails because the title already exists in the database. We have to skip unique validation for the resource that is being updated.
$validated = $request->validate([
'title' => 'required|max:255|unique:books,title,'.$book->id, // <-- change this
'author' => 'required|max:255'
]);
$book->update( $request->only(['title', 'author']) );

Laravel resource store method is being redirected to destroy method

I have a resource route
Route::resource('climb-excluded','CexcludedController',['only'=>['store','update','destroy']]);
And my code in view to save data
<div class="col-lg-4">
<form class="form" method="POST" action="{{ route('climb-excluded.store') }}">
{{ csrf_field() }}
<div class="card">
<div class="card-head style-primary">
<header>Add item</header>
</div>
<div class="card-body floating-label">
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<input type="text" class="form-control" id="name" name="name">
<label for="name">Name</label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<button type="submit"
class="btn btn-block btn-success ink-reaction">
Add
</button>
</div>
</div>
</div>
</div>
A button to destroy data:
{!! Form::open( array('route'=>array('climb-excluded.destroy', $excluded->id),
'method'=>'DELETE')) !!}
<button type="submit"
class="btn ink-reaction btn-floating-action btn-sm btn-danger "
rel="tooltip"
title="Delete">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button
{!! Form::close() !!}
Store method form controller:
public function store(Request $request)
{
$this->validate($request,[
'name' => 'required|max:255'
]);
$excluded = new Cexcluded;
$excluded -> name = $request->name;
$excluded->save();
//redirect to
Session::flash('success','New item sucessfully added !');
return back()->withInput(['tabs'=>'second4']);
}
Destroy method form controller:
public function destroy($id)
{
$trekExcluded = Cexcluded::find($id);
$trekExcluded->tours()->detach();
$trekExcluded ->delete();
Session::flash('success','Item sucessfully deleted !');
return back()->withInput(['tabs'=>'second4']);
}
The trouble/bug that I'm facing is I can insert first row into table successfully. But when I go for the second one, the store method is somehow redirected to destroy method and deletes the first inserted row also. While I've clearly declared store method in action attribute of the form.
FYI: Both routes exists in same view/page. Destroy method in col-md-8with foreach loop while store method in col-md-4
Its quite obvious, that your form don't have a unique name or id, so that's why the second method is redirected to destroy method. Do something like this:
cex-store-1
cex-destroy-1

Eloquent $model->update() does not make changes on database record

When I update my comment it goes back to the page and changes the comment back to orignal, so the update hasn't been done. No errors or something.
db: comments
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->integer('articleID')->unsigned();
$table->string('comment');
$table->timestamps();
});
model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
protected $fillable = ['comment', 'articleID'];
public function article() {
return $this->belongsTo('App\Article');
}
}
CommentsController
public function edit($commentID) {
$comment = Comment::findOrFail($commentID);
return view('pages.comments.edit', compact('comment'));
}
public function update($commentID, CommentRequest $request) {
$comment = Comment::findOrFail($commentID);
$comment->update($request->all());
return view('/');
}
editComment view
<form action="{{ route('updateComments', ['commentID' => $comment->id]) }}" class="form-horizontal" method="get">
{{ csrf_field() }}
{{ method_field('PATCH') }}
<!-- Article data -->
<div class="form-group">
<label class="col-sm-3 control-label" for="body">Comment</label>
<div class="col-sm-6">
<textarea class="form-control" id="body" name="body" maxlength="1000">{{ $comment->comment }}</textarea>
</div>
</div>
<!-- Add Article Button -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button class="btn btn-default" type="submit"><i class="fa fa-pencil-square-o"></i> Edit comment</button>
</div>
</div>
</form>
Your problem is:
You cannot do form submit with get method, even with hidden method_field('PATCH') in fact it does not event get to update action (:
Your form field name body is not correct if we look at fillable field of model
So just fix Your form:
<form
action="{{ route('updateComments', ['commentID' => $comment->id]) }}"
method="post"
class="form-horizontal">
{{ csrf_field() }}
<!-- Article data -->
<div class="form-group">
<label class="col-sm-3 control-label" for="comment">Comment</label>
<div class="col-sm-6">
<textarea
id="comment"
name="comment"
maxlength="1000"
class="form-control"
>{{ $comment->comment }}</textarea>
</div>
</div>
<!-- Add Article Button -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button class="btn btn-default" type="submit">
<i class="fa fa-pencil-square-o"></i> Edit comment
</button>
</div>
</div>
</form>
or change Your schema and model to have field called body not comment
p.s. also fix Your update action:
public function update(CommentRequest $request, $commentID) {
$comment = Comment::findOrFail($commentID);
$comment->update($request->except(['articleID'])); // for safety we are ignoring "possible existence" of articleID in forma
return redirect(route('updateComments', compact('commentID')));
}
doing return view('/') is not correct - it's trying to find file with name / that of course does not exist.

Laravel: Passing data through a controller results in MethodNotAllowedHttpException

I have seen this post, however I don't believe it is relevant to my issue because I believe I am correctly passing post data through a post route.
Here is the relevant route code:
Route::get('/pass', 'PageController#pass');
Route::post('/pass/{request}',['uses' => 'PageController#passController']);
I would like to have one controller method for the 'pass' page, but to isolate the issue I have separated them.
Here are the relevant methods in PageController.php:
public function pass(){
return view('pass')->with(array(
'title'=>'Create A Pass'
));
}
public function passRequest($request){
$data['request'] = $request;
$validator = Validator::make($request->all(), [
'studentID' => 'required|max:255',
'teacherID' => 'required|max:255',
'destination' => 'required|max:255',
]);
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
$pass = new Pass;
$pass->student = DB::table('users')->where('studentID', $request->studentID)->first()->id;
$pass->teacher = DB::table('users')->where('teacherID', $request->teacherID)->first()->id;
$pass->destination = $request->destination;
$pass->save();
return view('home')->with(array(
'title'=>'Home',
'success'=>'null'
));
}
I used the method stated here in order to pass data to the controller. If this is bad practice/obsolete I'm open to any suggestions.
This is the form in the 'pass' page responsible for sending the post data
<form action="{{ url('pass') }}" method="POST" class="form-horizontal">
{!! csrf_field() !!}
<fieldset>
<!-- Text input-->
<div class="container">
<div class="form-group">
<label class="col-md-4 control-label" for="studentID">Student ID</label>
<div class="col-md-3">
<input id="studentID" name="studentID" type="text" class="form-control input-md">
</div>
</div>
</div>
<!-- Text input-->
<div class="container">
<div class="form-group">
<label class="col-md-4 control-label" for="teacherID">Teacher ID</label>
<div class="col-md-3">
<input id="teacherID" name="teacherID" type="text" class="form-control input-md">
</div>
</div>
</div>
<!-- Text input-->
<div class="container">
<div class="form-group">
<label class="col-md-4 control-label" for="destination">Destination</label>
<div class="col-md-3">
<input id="destination" name="destination" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="container">
<div class="form-group">
<div class="col-sm-offset-4 col-sm-6">
<button type="submit" class="btn btn-default">
<i class="fa fa-check"></i> Create Pass
</button>
</div>
</div>
</div>
</fieldset>
</form>
On submission of this form I get the MethodNotAllowedHttpException Exception.
If a stack trace of the error would be helpful, please let me know. If there are any suggestions on style, I'm open to that as well.
This form tag will generate a POST request to the URL /pass:
<form action="{{ url('pass') }}" method="POST" class="form-horizontal">
Your routes file does not allow that. It only allows GET requests to that url, but POST requests to /pass/{request}.
Not sure if its just a copy/paste mistake, but your POST route is set up to call PageController#passController method, but the method you shared from your controller is named passRequest. Those will need to match also.
In addition to what Jeff Lambert pointed out, you should not put the {request} variable in the route.
You should remove that and have laravel inject the Request object for you.
Import the Request class if you haven't already at the top of the class.
use Illuminate\Http\Request;
And your function should look like the following...
public function passRequest(Request $request)
{
...
}
If you have additional parameters to pass through the URL, then you may add them to the route, and add the arguments to the method after Request $request. Laravel will figure out what to do with it.
try this one...
Route::post('/pass/post','PageController#passController')->name('post_insert');
in your html form change to ...
<form action="{{ route('post_insert') }}" method="POST" class="form-horizontal">
change it also ...
public function passRequest(Illuminate\Http\Request $request){
....

Creating New Forms in Laravel 5 and Submitting Them

I wish to clarify the steps to get a new form properly submitted to my database using Laravel 5.2 and Bootstrap 3.
I have the login/register pages set up properly using Laravel's defaults, and they work fine. I now want to create a user profile page accessible to authenticated users. I am using one row in the database for all of their user info. Some fields were filled in during registration, and now I want them to have access to additional fields (while restricting access to certain registration fields like user name).
In the example code below, there are fields to upload a personal photo, enter a first name, and enter a last name. (None of these were done during registration.)
What I have already done (all code is below):
Create the view profile.blade.php
Create a controller profileController.php
Update routes.php in the controller directory.
A note:
When I try to submit the form as it appears below, I get, Type error: Argument 1 passed to App\Http\Controllers\ProfileController::update() must be of the type array, none given.
What are the next steps required to get this page working properly?
profile.blade.php:
#extends('layouts.app')
#section('content')
<div class="container" style="padding-top: 30px;">
<h1 class="page-header">User Profile</h1>
<div class="row">
<!-- left column -->
<div class="col-md-4 col-sm-6 col-xs-12">
<div class="text-center">
<i class="fa fa-user fa-5x"></i>
<h6>Please upload a photo...</h6>
<input type="file" class="text-center center-block well well-sm">
</div>
</div>
<!-- edit form column -->
<div class="col-md-8 col-sm-6 col-xs-12 personal-info">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/profile') }}">
{!! csrf_field() !!}
<div class="form-group">
<label class="col-lg-3 control-label">First name:</label>
<div class="col-lg-8">
<input class="form-control" value="<?php echo Auth::user()->firstname; ?>" id="firstname" name="firstname" placeholder="First..." type="text">
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Last name:</label>
<div class="col-lg-8">
<input class="form-control" value="<?php echo Auth::user()->lastname; ?>" id="lastname" name="lastname" placeholder="Last..." type="text">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label"></label>
<div class="col-md-8">
<button type="submit" class="btn btn-primary">
<i class="fa fa-btn fa-user"></i>Submit
</button>
<span></span>
<input class="btn btn-default" value="Cancel" type="reset">
</div>
</div>
</form>
</div>
</div>
</div>
#endsection
profileController.php:
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
class ProfileController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return view('profile');
}
protected function update(array $data)
{
return User::update([
'firstname' => $data['firstname'],
'lastname' => $data['lastname'],
]);
}
}
And I added the following in the routes middleware:
Route::get('/profile', 'ProfileController#index');
Route::post('/profile', 'ProfileController#update');
It's a protocol mismatch, since you're POSTing your form. You need to change your route to
route::post('/profile', 'ProfileController#index');
Using a validator is a great idea, since it will make sure that your input is exactly what you need it to be, and all required fields are filled out.
Your update function should look something like this:
public function update(Request $request)
{
$first_name = $request->input('firstname');
$last_name = $request->input('lastname');
$id = Auth::user()->id;
$user = \App\User::find($id);
$user->firstname = $first_name;
$user->lastname = $last_name;
$user->save();
return view('profile');
// Sanitize, validate, before you do ANYTHING with update
// Instead of returning the update result, you can instead show another view or forward them to another page.
}

Categories