메인 콘텐츠로 건너뛰기

검증이란

검증이란, 사용자로부터 송신된 데이터가 기대하는 형식이나 조건을 만족하고 있는지를 검증하는 것입니다. Laravel은 리퀘스트 오브젝트의 validate 메서드나 전용의 폼 리퀘스트 클래스를 사용한, 심플하고 강력한 검증 기능을 제공하고 있습니다.

컨트롤러에서의 검증

$request->validate()의 사용법

컨트롤러의 메서드 내에서 $request->validate()를 호출하는 것이, 가장 심플한 검증 방법입니다. 검증에 실패하면, Laravel은 사용자를 이전 화면으로 자동으로 리다이렉트하고, 에러 정보를 세션에 보존합니다. 라우트를 정의합니다.
use App\Http\Controllers\PostController;

Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);
컨트롤러를 작성합니다.
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class PostController extends Controller
{
    public function create(): View
    {
        return view('post.create');
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'body'  => 'required|string',
            'email' => 'required|email',
        ]);

        // 검증 완료 데이터로 투고를 보존...

        return redirect('/posts');
    }
}
validate 메서드에는 필드명을 키, 규칙을 값으로 한 배열을 전달합니다. 규칙은 파이프 |로 구분하거나, 배열로 지정할 수 있습니다.
// 파이프 구분
'title' => 'required|string|max:255',

// 배열 형식
'title' => ['required', 'string', 'max:255'],

주요 검증 규칙

규칙설명
required값이 존재하고, 비어 있지 않을 것
string문자열일 것
email유효한 메일 주소 형식일 것
min:값문자열의 길이, 또는 수치가 지정 값 이상일 것
max:값문자열의 길이, 또는 수치가 지정 값 이하일 것
unique:테이블지정한 테이블에서 값이 일의일 것
nullable값이 null이어도 허가
integer정수일 것
boolean진위값 (true/false, 1/0 등)일 것
date유효한 날짜 형식일 것
confirmed필드명_confirmation 필드와 일치할 것
이용 가능한 모든 검증 규칙은 공식 문서에서 확인할 수 있습니다.

검증 완료 데이터의 이용

validate 메서드의 반환값은, 검증에 통과한 데이터만을 포함하는 배열입니다. 신뢰할 수 있는 데이터로서 안전하게 사용할 수 있습니다.
$validated = $request->validate([
    'title' => 'required|string|max:255',
    'body'  => 'required|string',
]);

// $validated는 ['title' => '...', 'body' => '...']의 형식
Post::create($validated);

Blade 템플릿에서의 에러 표시

검증에 실패하면, Laravel은 $errors 변수를 모든 뷰에서 자동적으로 이용할 수 있도록 합니다. web 미들웨어 그룹에 포함되는 ShareErrorsFromSession 미들웨어가 이를 담당하고 있습니다.

모든 에러를 일람 표시

@if ($errors->any())
    <ul>
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

필드별로 에러를 표시

@error 디렉티브를 사용하면, 특정 필드의 에러를 인라인으로 표시할 수 있습니다.
<label for="title">타이틀</label>

<input
    id="title"
    type="text"
    name="title"
    value="{{ old('title') }}"
    class="@error('title') is-invalid @enderror"
/>

@error('title')
    <div class="error-message">{{ $message }}</div>
@enderror
old('필드명')을 사용하면, 검증 실패 후에도 사용자가 입력한 값을 폼에 재표시할 수 있습니다.

폼 리퀘스트

폼 리퀘스트란

검증 로직이 복잡해진 경우는, “폼 리퀘스트” 클래스에 잘라 내는 것이 효과적입니다. 폼 리퀘스트는 검증과 인가의 로직을 하나의 클래스에 정리한 커스텀 리퀘스트 클래스입니다.

폼 리퀘스트의 작성

make:request Artisan 명령으로 폼 리퀘스트 클래스를 생성합니다.
php artisan make:request StorePostRequest
app/Http/Requests/StorePostRequest.php가 생성됩니다.
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    /**
     * 이 리퀘스트를 실행할 권한이 있는지 판정한다
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * 이 리퀘스트에 적용할 검증 규칙을 반환한다
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'title' => 'required|string|max:255',
            'body'  => 'required|string',
            'email' => 'required|email|unique:posts',
        ];
    }
}

rules() 메서드

검증 규칙을 배열로 반환합니다. 컨트롤러의 validate 메서드에 전달하는 배열과 같은 형식입니다.

authorize() 메서드

이 리퀘스트를 실행할 권한이 있는지를 판정합니다. true를 반환하면 인가 OK, false를 반환하면 403 응답이 자동적으로 반환됩니다. 인증된 사용자만 허가하는 경우, auth()->check()로 확인할 수 있습니다. 튜토리얼에서는 true를 반환해 두면 문제없습니다.
authorize 메서드가 false를 반환하면, 컨트롤러의 메서드는 실행되지 않고, 403 Forbidden 응답이 반환됩니다.

컨트롤러에의 주입

폼 리퀘스트는 컨트롤러 메서드의 타입 힌트로서 지정하는 것만으로 사용할 수 있습니다. 컨트롤러가 호출되기 전에 검증이 실행되기 때문에, 메서드 내에 검증 코드를 작성할 필요는 없습니다.
use App\Http\Requests\StorePostRequest;

class PostController extends Controller
{
    public function store(StorePostRequest $request): RedirectResponse
    {
        // 여기에 도달한 시점에서 검증 완료

        $validated = $request->validated();

        Post::create($validated);

        return redirect('/posts');
    }
}
$request->validated()로 검증 완료 데이터만을 취득할 수 있습니다.

실천 예: 투고 폼의 작성과 보존

폼의 표시부터 송신·검증·보존까지의 일련의 플로우입니다.
1

라우트의 정의

use App\Http\Controllers\PostController;

Route::get('/posts/create', [PostController::class, 'create']);
Route::post('/posts', [PostController::class, 'store']);
2

폼 리퀘스트의 작성

php artisan make:request StorePostRequest
public function rules(): array
{
    return [
        'title' => 'required|string|max:255',
        'body'  => 'required|string',
    ];
}

public function authorize(): bool
{
    return true;
}
3

컨트롤러의 구현

use App\Http\Requests\StorePostRequest;
use App\Models\Post;

class PostController extends Controller
{
    public function create(): View
    {
        return view('posts.create');
    }

    public function store(StorePostRequest $request): RedirectResponse
    {
        Post::create($request->validated());

        return redirect('/posts');
    }
}
4

Blade 템플릿의 작성

{{-- resources/views/posts/create.blade.php --}}

<h1>새로운 투고</h1>

@if ($errors->any())
    <ul>
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

<form method="POST" action="/posts">
    @csrf

    <div>
        <label for="title">타이틀</label>
        <input
            id="title"
            type="text"
            name="title"
            value="{{ old('title') }}"
        />
        @error('title')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <div>
        <label for="body">본문</label>
        <textarea id="body" name="body">{{ old('body') }}</textarea>
        @error('body')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <button type="submit">투고하기</button>
</form>
Blade 폼에는 반드시 @csrf 디렉티브를 포함해 주세요. CSRF 토큰이 없으면 Laravel은 419 에러를 반환합니다.

다음 단계

HTTP 리퀘스트

리퀘스트 오브젝트를 사용한 데이터 취득 방법을 되돌아봅니다.
마지막 수정일 2026년 7월 13일