How to sanitize user input with Laravel Livewire
So Laravel Livewire, you've heard of it and by having a look at this post i'm hoping you love working with it too? We're off to a great start if so!
In this post i'll show you some ways to sanitize user input and it's easier than you might think. Here are a few ways to do it:
Sanitize user input in your Livewire Component
- Sanitize the input directly when creating or updating your model.
- Create a separate method and pass your input to it before creating or updating your model.
- Create a Form Request and call it from your $rules array
Sanitize the input directly
If the model you are creating or updating doesn't contain many fields or you simply don't prefer the other methods, you can perform your sanitization directly. Here's an example:
namespace App\Http\Livewire;
use App\Models\Review;
use Livewire\Component;
use Illuminate\Validation\Rule;
class CreateReview extends Component
{
public $title;
public $body;
public $rating;
public function submit()
{
$this->validate([
'title' => ['required', 'string', 'max:100'],
'body' => ['required', 'string', 'max:500'],
'rating' => ['required', Rule::in([1, 2, 3, 4, 5])]
]);
$review = Review::create([
'user_id' => auth()->user()->id,
'title' => filter_var($this->title, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES),
'body' => filter_var($this->body, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES),
'rating' => $this->rating
]);
session()->flash('message', 'Thanks, your review has been submitted.');
}
public function render()
{
return view('livewire.create-review');
}
}
In the example above, I've got a Livewire component which creates a review. I want to sanitize the user input which is the review title and body. You can simply use your sanitization techniques when creating / updating the model. Nice and easy, however not the cleanest or prettiest.
Create a separate method and pass your input to it
If you prefer to move your sanitization outside of your main submit method, you can create a separate method and do the sanitization from there instead. Using the review component, let's amend it slightly:
public function submit()
{
$this->sanitize();
$this->validate([
'title' => ['required', 'string', 'max:100'],
'body' => ['required', 'string', 'max:500'],
'rating' => ['required', Rule::in([1, 2, 3, 4, 5])]
]);
$review = Review::create([
'user_id' => auth()->user()->id,
'title' => $this->title,
'body' => $this->body,
'rating' => $this->rating
]);
session()->flash('message', 'Thanks, your review has been submitted.');
}
public function sanitize()
{
$this->title = filter_var($this->title, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
$this->rating = filter_var($this->rating, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
}
In this example we've created a sanitize method and we call it before our validation step, as we still want to know if the sanitized data will pass validation. We've also tidied up our create method.
Create a Form Request and call it from your $rules array
I picked this one up from Micheal Rubel and his fantastic Livewire Best Practices.
Since Livewire doesn't currently support Form Request (But it looks like its being worked on) you can't do all your usual validation and sanitization in the livewire component. However what you can do is return the form request from the $rules array like so:
public function rules(): array
{
return (new ReviewRequest)->rules();
}
Using this method you can create your Form Requests as you normally would and implement your own sanitization rules in the prepareForValidation()
method. See the Laravel documentation on how to use it.