미들웨어란
미들웨어는 애플리케이션에 도달하는 HTTP 요청을 검사·필터링하는 구조입니다.
요청이 컨트롤러에 전달되기 전후에 처리를 끼워 넣을 수 있습니다.
예를 들어 Laravel에는 인증 미들웨어가 포함되어 있습니다.
사용자가 인증되지 않은 경우에는 로그인 화면으로 리다이렉트하고, 인증된 경우에는 요청을 그대로 애플리케이션 내부로 통과시킵니다.
인증 외에도 로그 기록·CSRF 보호·레이트 제한 등 다양한 목적으로 미들웨어를 만들 수 있습니다. Laravel 13의 CSRF 보호 상세는 CSRF 보호 를 참조해 주세요.
사용자가 정의한 미들웨어는 일반적으로 app/Http/Middleware 디렉터리에 배치합니다.
내장 미들웨어
Laravel은 기본적으로 web과 api 두 개의 미들웨어 그룹을 준비하고 있습니다.
routes/web.php에는 web 그룹이, routes/api.php에는 api 그룹이 자동으로 적용됩니다.
web 미들웨어 그룹EncryptCookiesAddQueuedCookiesToResponseStartSessionShareErrorsFromSessionPreventRequestForgery (CSRF 보호)SubstituteBindings
또한 자주 사용되는 미들웨어에는 별칭이 설정되어 있어 짧은 이름으로 참조할 수 있습니다.
별칭 미들웨어 authIlluminate\Auth\Middleware\AuthenticateguestIlluminate\Auth\Middleware\RedirectIfAuthenticatedverifiedIlluminate\Auth\Middleware\EnsureEmailIsVerifiedthrottleIlluminate\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.php의 withMiddleware로 글로벌 스택에 추가합니다.
// 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 요청 컨트롤러에서 요청 데이터를 받는 방법을 배웁니다.