Form trong Blade
<form method="POST" action="{{ route('products.store') }}">
@csrf
<input name="name" value="{{ old('name') }}">
@error('name') <p class="error">{{ $message }}</p> @enderror
<input name="price" type="number" value="{{ old('price') }}">
<button type="submit">Lưu</button>
</form>
@csrfchèn token chống giả mạo request. Thiếu nó, Laravel trả lỗi 419.- Form HTML chỉ có GET và POST. Muốn PUT hay DELETE, thêm
@method('PUT')vào form. old()giữ lại giá trị người dùng đã nhập khi validation thất bại;@errorhiện lỗi của từng ô.
Validation nhanh trong controller
public function store(Request $request)
{
$data = $request->validate([
'name' => ['required', 'string', 'max:120'],
'price' => ['required', 'integer', 'min:1000'],
'category_id' => ['required', 'exists:categories,id'],
]);
Product::create($data + ['slug' => str($data['name'])->slug()]);
return to_route('products.index')->with('status', 'Đã thêm sản phẩm');
}
Sai quy tắc thì Laravel tự quay lại form kèm lỗi. Nếu request muốn JSON (API), Laravel trả về lỗi 422 dạng JSON.
Form Request: tách validation ra class riêng
php artisan make:request StoreProductRequest
class StoreProductRequest extends FormRequest
{
public function authorize(): bool
{
return $this->user() !== null; // ai được gửi form này
}
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:120'],
'price' => ['required', 'integer', 'min:1000'],
];
}
}
public function store(StoreProductRequest $request)
{
Product::create($request->validated()); // chỉ lấy các trường đã qua kiểm tra
}
So với Next.js: rules() giống schema Zod, validated() giống kết quả safeParse thành công.
Ba quy tắc bảo mật
- Gán hàng loạt: luôn dùng
$request->validated()hoặc chỉ định từng trường. Đừng truyền$request->all()vào create. - CSRF: mọi form POST trong web phải có @csrf. Laravel 13 đổi tên middleware này thành PreventRequestForgery và kiểm tra thêm header Sec-Fetch-Site; code cũ gọi là VerifyCsrfToken.
- XSS: in dữ liệu bằng hai dấu ngoặc nhọn của Blade (tự escape). Chỉ in thô khi chắc chắn nội dung an toàn.
Bài tập
- Làm form tạo sản phẩm có chọn danh mục.
- Viết StoreProductRequest, hiện lỗi dưới từng ô, giữ giá trị cũ khi lỗi.
- Sau khi lưu, chuyển về danh sách và hiện thông báo "Đã thêm sản phẩm" bằng
session('status'). - Thử xóa @csrf khỏi form và quan sát lỗi 419.
Xem thêm
- 30 Days to Learn Laravel, Ep 17 - Always Validate. Never Trust the User. (kênh Laracasts, tiếng Anh, 14 phút)
- Unlocking the Power of Form Requests in Laravel (kênh Laravel, tiếng Anh, 9 phút)
- Bài 8: Xác thực dữ liệu đầu vào với Request Validation (kênh Hải Đăng Dev, tiếng Việt, 23 phút)