Middleware
![](https://www.stackhoarder.com/wp-content/uploads/2019/08/image-22.png)
일반적으로 Middleware 라는 용어는 Application 과 OS (운영체제) 사이에 존재하는 컴퓨터 소프트웨어 (software glue) 라고 불립니다. 이 미들웨어는 둘 사이의 연결 역할을 하면서 중간에서 특정한 기능을 수행합니다.
![](https://www.stackhoarder.com/wp-content/uploads/2019/08/image-23.png)
어플리케이션 내부에서도 같은 의미로 미들웨어가 사용됩니다. 어플리케이션은 요청에 알맞은 처리를 진행한 후 응답을 하는 일을 합니다. 미들웨어는 이 요청과 응답 사이에 존재하여 특정한 기능을 수행합니다. 요청을 통과시켜 응답을 얻는다라는 개념도 틀린 말이 아닙니다. ( 스프링에서 AOP, Filter, intercept 개념과 비슷하다고 보시면 됩니다. )
Laravel Middleware
라라벨에서도 위와 같이 어플리케이션 미들웨어를 제공합니다. 어플리케이션 관점에서 미들웨어의 제일 쉬운 예제로 사용자 인증을 들 수 있겠습니다. 보통 웹 어플리케이션에서 사용자 정보 페이지를 요청하는 경우에 인증 미들웨어를 통과시켜 성공하는 경우 사용자 정보 페이지를 응답, 실패하는 경우 로그인 페이지로 리다이렉트하는 개념으로 사용됩니다.
![](https://www.stackhoarder.com/wp-content/uploads/2019/08/image-24-1024x600.png)
미들웨어 정의하기
지금부터는 미들웨어를 직접 만들어 사용해보겠습니다. 앞선 포스팅에서 Service Provider 생성한 것처럼 Laravel Artisan 를 이용해 커맨드 명령어로 생성하겠습니다.
php artisan make:middleware LogUserAccess
![](https://www.stackhoarder.com/wp-content/uploads/2019/08/image-25.png)
app/Http/middleware 디렉토리 아래에는 이미 라라벨에서 구현해놓은 미들웨어들이 존재합니다. 인증, 쿠키, CSRF Token 관련된 미들웨어들이 존재합니다.
app/Http/middleware/LogUserAccess.php 파일을 열어보겠습니다.
<?php namespace App\Http\Middleware; use Closure; class LogUserAccess { public function handle($request, Closure $next) { // 미들웨어 중간 기능 // Request를 탈취??하여 사용자 접속 로그를 남김.. // ... // return $next($request); } }
미들웨어는 구현이 단순합니다. Request 를 사용하여 해당 작업을 수행 후 Closure인 $next($request) 를 리턴합니다. 도중에 Request 를 탈취하여 사용한 뒤 그대로 반환 한다는 의미입니다.
모든 작업을 수행한 뒤에 미들웨어를 통과시키는 코드도 가능합니다. 이런 경우에는 Closure 작업을 마친 후에 해당 미들웨어 동작을 수행할 것입니다.
public function handle($request, Closure $next) { // Closure 의 다른 작업을 마친 결과를 받아 $response = $next($request); // 사용자 로그를 남김 return $response; }
미들웨어 등록하기
미들웨어를 작성하였다면 Application에 등록하는 작업을 수행하여야합니다. app/Http/Kernel.app 에 등록하면 됩니다.
<?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel { // Global Middleware protected $middleware = [ \App\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, \App\Http\Middleware\TrustProxies::class, ]; // Grouped Middleware // Route 디렉토리에선 다음과 같이 사용된다. // Route::get('/', function () {})->middleware('web'); // Route::group(['middleware' => ['web']], function () {}); protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ 'throttle:60,1', 'bindings', ], ]; // Route Middleware // Route 디렉토리에서 다음과 같이 사용 된다. // Route::get('/', function () {})->middleware('first', 'second'); protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, ]; // Define Middleware Priority protected $middlewarePriority = [ \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\Authenticate::class, \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class, ]; }
- $middleware => 전역으로 사용되는 미들웨어를 등록합니다.
- $middlewareGroups => 그룹으로 미들웨어를 묶어서 사용합니다.
- $routeMiddleware => 라우트에서 사용될 미들웨어를 정의합니다.
- $middlewarePriority => 미들웨어의 순서를 정의합니다.
작성하는 미들웨어 기능에 맞게 등록하면 됩니다.
TL;DR
- 라라벨에서 미들웨어는 요청을 탈취하여 정의한 기능을 수행한 뒤 응답을 돌려준다. (통과의 개념)
- 라라벨에서는 인증, 쿠키, CRSF 토큰 관련 미들웨어들이 구현되어 있다.
- middleware를 정의한 뒤 app/Http/Kernel.php 에 기능에 맞는 미들웨어 등록 단계를 거친다.