> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 미들웨어

> Laravel의 미들웨어를 사용해 HTTP 요청의 필터링과 전처리를 수행하는 방법을 설명합니다.

## 미들웨어란

미들웨어는 애플리케이션에 도달하는 HTTP 요청을 검사·필터링하는 구조입니다.
요청이 컨트롤러에 전달되기 전후에 처리를 끼워 넣을 수 있습니다.

예를 들어 Laravel에는 인증 미들웨어가 포함되어 있습니다.
사용자가 인증되지 않은 경우에는 로그인 화면으로 리다이렉트하고, 인증된 경우에는 요청을 그대로 애플리케이션 내부로 통과시킵니다.

인증 외에도 로그 기록·CSRF 보호·레이트 제한 등 다양한 목적으로 미들웨어를 만들 수 있습니다. Laravel 13의 CSRF 보호 상세는 [CSRF 보호](/ko/csrf)를 참조해 주세요.

<Info>
  사용자가 정의한 미들웨어는 일반적으로 `app/Http/Middleware` 디렉터리에 배치합니다.
</Info>

```mermaid theme={null}
flowchart TD
    A["HTTP 요청"] --> B["글로벌 미들웨어<br>(모든 요청에 적용)"]
    B --> C["라우트 미들웨어<br>(특정 라우트에 적용)"]
    C --> D["컨트롤러 / 클로저"]
    D --> E["응답 생성"]
    E --> F["라우트 미들웨어<br>(후처리)"]
    F --> G["글로벌 미들웨어<br>(후처리)"]
    G --> H["HTTP 응답"]
```

## 내장 미들웨어

Laravel은 기본적으로 `web`과 `api` 두 개의 미들웨어 그룹을 준비하고 있습니다.
`routes/web.php`에는 `web` 그룹이, `routes/api.php`에는 `api` 그룹이 자동으로 적용됩니다.

| `web` 미들웨어 그룹                     |
| --------------------------------- |
| `EncryptCookies`                  |
| `AddQueuedCookiesToResponse`      |
| `StartSession`                    |
| `ShareErrorsFromSession`          |
| `PreventRequestForgery` (CSRF 보호) |
| `SubstituteBindings`              |

또한 자주 사용되는 미들웨어에는 별칭이 설정되어 있어 짧은 이름으로 참조할 수 있습니다.

| 별칭         | 미들웨어                                                 |
| ---------- | ---------------------------------------------------- |
| `auth`     | `Illuminate\Auth\Middleware\Authenticate`            |
| `guest`    | `Illuminate\Auth\Middleware\RedirectIfAuthenticated` |
| `verified` | `Illuminate\Auth\Middleware\EnsureEmailIsVerified`   |
| `throttle` | `Illuminate\Routing\Middleware\ThrottleRequests`     |

## 미들웨어 생성

`make:middleware` Artisan 명령으로 새 미들웨어를 만듭니다.

```shell theme={null}
php artisan make:middleware EnsureTokenIsValid
```

`app/Http/Middleware/EnsureTokenIsValid.php`가 생성됩니다.
`handle` 메서드에 요청을 처리하는 로직을 작성합니다.

```php theme={null}
<?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)`를 호출하면 요청이 애플리케이션의 다음 처리로 전달됩니다.
조건을 충족하지 않는 경우에는 리다이렉트나 응답을 반환해 요청을 멈춥니다.

### 요청 전후의 처리

미들웨어는 요청 **전** 또는 **후**에 처리를 실행할 수 있습니다.

```php theme={null}
// 요청 전에 처리한다
public function handle(Request $request, Closure $next): Response
{
    // 여기에 전처리를 작성한다

    return $next($request);
}
```

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

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

    return $response;
}
```

## 미들웨어 등록

### 글로벌 미들웨어

모든 요청에 대해 미들웨어를 실행하고 싶은 경우, `bootstrap/app.php`의 `withMiddleware`로 글로벌 스택에 추가합니다.

```php theme={null}
// 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` 메서드를 호출합니다.

```php theme={null}
use App\Http\Middleware\EnsureTokenIsValid;

Route::get('/profile', function () {
    // ...
})->middleware(EnsureTokenIsValid::class);
```

여러 미들웨어를 적용하는 경우에는 배열로 전달합니다.

```php theme={null}
Route::get('/', function () {
    // ...
})->middleware([First::class, Second::class]);
```

특정 라우트에서만 미들웨어를 제외하고 싶은 경우에는 `withoutMiddleware`를 사용합니다.

```php theme={null}
use App\Http\Middleware\EnsureTokenIsValid;

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

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

### 미들웨어 별칭

긴 클래스명에 짧은 별칭을 정의할 수 있습니다. `bootstrap/app.php`에서 설정합니다.

```php theme={null}
// bootstrap/app.php
use App\Http\Middleware\EnsureUserIsSubscribed;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->alias([
            'subscribed' => EnsureUserIsSubscribed::class,
        ]);
    });
```

별칭을 사용해 라우트에 적용할 수 있습니다.

```php theme={null}
Route::get('/profile', function () {
    // ...
})->middleware('subscribed');
```

## 미들웨어 그룹

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

```php theme={null}
// 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,
        ]);
    });
```

그룹은 라우트에 일반 미들웨어와 같은 방법으로 적용할 수 있습니다.

```php theme={null}
Route::get('/', function () {
    // ...
})->middleware('group-name');

Route::middleware(['group-name'])->group(function () {
    // ...
});
```

기존의 `web` 그룹이나 `api` 그룹에 미들웨어를 추가하는 경우에는 전용 메서드를 사용할 수 있습니다.

```php theme={null}
// 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 theme={null}
<?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);
    }
}
```

라우트 정의에서 미들웨어명과 파라미터를 `:`로 구분해 지정합니다.

```php theme={null}
use App\Http\Middleware\EnsureUserHasRole;

Route::put('/post/{id}', function (string $id) {
    // ...
})->middleware(EnsureUserHasRole::class.':editor');
```

여러 파라미터는 쉼표로 구분합니다.

```php theme={null}
Route::put('/post/{id}', function (string $id) {
    // ...
})->middleware(EnsureUserHasRole::class.':editor,publisher');
```

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

로그인하지 않은 사용자를 리다이렉트하는 단순한 예시입니다.

```shell theme={null}
php artisan make:middleware RedirectIfNotAuthenticated
```

```php theme={null}
<?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);
    }
}
```

라우트에 적용합니다.

```php theme={null}
Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(RedirectIfNotAuthenticated::class);
```

<Tip>
  Laravel에는 인증용 `auth` 미들웨어가 내장되어 있습니다. 직접 구현하기 전에 기존 미들웨어로 요구 사항을 충족할 수 있는지 확인합시다.
</Tip>

## 다음 단계

<Card title="HTTP 요청" icon="globe" href="/ko/requests">
  컨트롤러에서 요청 데이터를 받는 방법을 배웁니다.
</Card>


## Related topics

- [Laravel AI SDK](/ko/ai-sdk.md)
- [OAuth 2.0 인증 - Google Sheets API for Laravel](/ko/packages/laravel-google-sheets/oauth.md)
- [Laravel Pennant](/ko/pennant.md)
- [Laravel Folio](/ko/folio.md)
- [Laravel Sentinel — 라우트 보호 미들웨어 조사](/ko/blog/sentinel-introduction.md)
