메인 콘텐츠로 건너뛰기

미들웨어란

미들웨어는 애플리케이션에 도달하는 HTTP 요청을 검사·필터링하는 구조입니다. 요청이 컨트롤러에 전달되기 전후에 처리를 끼워 넣을 수 있습니다. 예를 들어 Laravel에는 인증 미들웨어가 포함되어 있습니다. 사용자가 인증되지 않은 경우에는 로그인 화면으로 리다이렉트하고, 인증된 경우에는 요청을 그대로 애플리케이션 내부로 통과시킵니다. 인증 외에도 로그 기록·CSRF 보호·레이트 제한 등 다양한 목적으로 미들웨어를 만들 수 있습니다. Laravel 13의 CSRF 보호 상세는 CSRF 보호를 참조해 주세요.
사용자가 정의한 미들웨어는 일반적으로 app/Http/Middleware 디렉터리에 배치합니다.

내장 미들웨어

Laravel은 기본적으로 webapi 두 개의 미들웨어 그룹을 준비하고 있습니다. routes/web.php에는 web 그룹이, routes/api.php에는 api 그룹이 자동으로 적용됩니다.
web 미들웨어 그룹
EncryptCookies
AddQueuedCookiesToResponse
StartSession
ShareErrorsFromSession
PreventRequestForgery (CSRF 보호)
SubstituteBindings
또한 자주 사용되는 미들웨어에는 별칭이 설정되어 있어 짧은 이름으로 참조할 수 있습니다.
별칭미들웨어
authIlluminate\Auth\Middleware\Authenticate
guestIlluminate\Auth\Middleware\RedirectIfAuthenticated
verifiedIlluminate\Auth\Middleware\EnsureEmailIsVerified
throttleIlluminate\Routing\Middleware\ThrottleRequests

미들웨어 생성

make:middleware Artisan 명령으로 새 미들웨어를 만듭니다.
php artisan make:middleware EnsureTokenIsValid
app/Http/Middleware/EnsureTokenIsValid.php가 생성됩니다. handle 메서드에 요청을 처리하는 로직을 작성합니다.
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureTokenIsValid
{
    /**
     * 수신 요청을 처리한다
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        if ($request->input('token') !== 'my-secret-token') {
            return redirect('/home');
        }

        return $next($request);
    }
}
$next($request)를 호출하면 요청이 애플리케이션의 다음 처리로 전달됩니다. 조건을 충족하지 않는 경우에는 리다이렉트나 응답을 반환해 요청을 멈춥니다.

요청 전후의 처리

미들웨어는 요청 또는 에 처리를 실행할 수 있습니다.
// 요청 전에 처리한다
public function handle(Request $request, Closure $next): Response
{
    // 여기에 전처리를 작성한다

    return $next($request);
}
// 응답 후에 처리한다
public function handle(Request $request, Closure $next): Response
{
    $response = $next($request);

    // 여기에 후처리를 작성한다

    return $response;
}

미들웨어 등록

글로벌 미들웨어

모든 요청에 대해 미들웨어를 실행하고 싶은 경우, bootstrap/app.phpwithMiddleware로 글로벌 스택에 추가합니다.
// bootstrap/app.php
use App\Http\Middleware\EnsureTokenIsValid;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->append(EnsureTokenIsValid::class);
    });
append는 스택의 끝에 추가합니다. 앞에 추가하려면 prepend를 사용합니다.

라우트로의 미들웨어 적용

특정 라우트에만 미들웨어를 적용하려면 라우트 정의에서 middleware 메서드를 호출합니다.
use App\Http\Middleware\EnsureTokenIsValid;

Route::get('/profile', function () {
    // ...
})->middleware(EnsureTokenIsValid::class);
여러 미들웨어를 적용하는 경우에는 배열로 전달합니다.
Route::get('/', function () {
    // ...
})->middleware([First::class, Second::class]);
특정 라우트에서만 미들웨어를 제외하고 싶은 경우에는 withoutMiddleware를 사용합니다.
use App\Http\Middleware\EnsureTokenIsValid;

Route::middleware([EnsureTokenIsValid::class])->group(function () {
    Route::get('/', function () {
        // 이 라우트에는 미들웨어가 적용된다
    });

    Route::get('/profile', function () {
        // 이 라우트는 미들웨어를 제외
    })->withoutMiddleware([EnsureTokenIsValid::class]);
});

미들웨어 별칭

긴 클래스명에 짧은 별칭을 정의할 수 있습니다. bootstrap/app.php에서 설정합니다.
// bootstrap/app.php
use App\Http\Middleware\EnsureUserIsSubscribed;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->alias([
            'subscribed' => EnsureUserIsSubscribed::class,
        ]);
    });
별칭을 사용해 라우트에 적용할 수 있습니다.
Route::get('/profile', function () {
    // ...
})->middleware('subscribed');

미들웨어 그룹

여러 미들웨어를 하나의 키로 묶으면 라우트로의 적용이 간단해집니다. bootstrap/app.php에서 appendToGroup 또는 prependToGroup을 사용합니다.
// bootstrap/app.php
use App\Http\Middleware\First;
use App\Http\Middleware\Second;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->appendToGroup('group-name', [
            First::class,
            Second::class,
        ]);
    });
그룹은 라우트에 일반 미들웨어와 같은 방법으로 적용할 수 있습니다.
Route::get('/', function () {
    // ...
})->middleware('group-name');

Route::middleware(['group-name'])->group(function () {
    // ...
});
기존의 web 그룹이나 api 그룹에 미들웨어를 추가하는 경우에는 전용 메서드를 사용할 수 있습니다.
// bootstrap/app.php
use App\Http\Middleware\EnsureUserIsSubscribed;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->web(append: [
            EnsureUserIsSubscribed::class,
        ]);
    });

미들웨어 파라미터

미들웨어는 추가 파라미터를 받을 수 있습니다. handle 메서드의 $next 인수 뒤에 파라미터를 추가합니다.
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureUserHasRole
{
    public function handle(Request $request, Closure $next, string $role): Response
    {
        if (! $request->user()->hasRole($role)) {
            return redirect('/home');
        }

        return $next($request);
    }
}
라우트 정의에서 미들웨어명과 파라미터를 :로 구분해 지정합니다.
use App\Http\Middleware\EnsureUserHasRole;

Route::put('/post/{id}', function (string $id) {
    // ...
})->middleware(EnsureUserHasRole::class.':editor');
여러 파라미터는 쉼표로 구분합니다.
Route::put('/post/{id}', function (string $id) {
    // ...
})->middleware(EnsureUserHasRole::class.':editor,publisher');

실전 예시: 인증 체크 미들웨어

로그인하지 않은 사용자를 리다이렉트하는 단순한 예시입니다.
php artisan make:middleware RedirectIfNotAuthenticated
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class RedirectIfNotAuthenticated
{
    public function handle(Request $request, Closure $next): Response
    {
        if (! $request->user()) {
            return redirect('/login');
        }

        return $next($request);
    }
}
라우트에 적용합니다.
Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(RedirectIfNotAuthenticated::class);
Laravel에는 인증용 auth 미들웨어가 내장되어 있습니다. 직접 구현하기 전에 기존 미들웨어로 요구 사항을 충족할 수 있는지 확인합시다.

다음 단계

HTTP 요청

컨트롤러에서 요청 데이터를 받는 방법을 배웁니다.
마지막 수정일 2026년 7월 13일