Lumen의 인증 구조는 사실 그렇게 복잡하지 않아요. 그런데 언뜻 봐서는 이해하기 어렵죠. Lumen이 「Laravel의 서브시스템」이라는 원죄를 짊어지고 있어서, 문서부터 코드까지 크게 간략화돼 있기 때문이에요 —— Laravel 코드까지 거슬러 올라가 보지 않으면 전체 그림이 도무지 잡히지 않을 만큼요(예를 들어 Lumen의 config/auth.php와 Laravel의 config/auth.php).
Laravel을 거치지 않고 곧장 Lumen을 접한 개발자라면, 문제에 부딪히거나 기능을 더하고 싶어졌을 때 취하는 행동은 대개 「공식 문서 찾기 → 인터넷 정보 찾기 → 소스 코드 읽어 보기」 중 하나예요. 그런데 공식 문서는 분명하게 쓰여 있지 않고, 인터넷 정보도 흐릿하고, 소스를 따라가도 (Laravel에 비해) 추상화 계층과 코드상의 정보가 부족한 탓에 꽤 만만치 않아요. 전체 구성을 정리해서 파악하기까지 꽤 여분의 품이 들죠.
그래서 저는 이 시리즈를 쓰고 있어요. 다른 순수 Lumen 개발자들이 좀 더 빨리 전체 그림을 잡고, 멀리 돌아가는 길을 조금이라도 줄일 수 있으면 좋겠다는 마음이에요.
설정 파일의 수수께끼
Lumen의 인증 관리를 이해하려면, 설정 파일부터 들어가는 게 좋은 출발점이에요. 다만 볼 건 Laravel의 config/auth.php 쪽이에요. 이 파일은 Lumen 쪽 것과 옵션도 파라미터도 거의 같지만, 더 충실한 정보를 줘요.
인증을 활성화했을 때의 기본값
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
설정 파일의 첫 번째 블록은 시스템 기본 Guard의 이름을 web으로, 기본 비밀번호 재설정 모듈을 users로 정의하고 있어요(비밀번호 쪽은 이 시리즈의 대상이 아니에요).
Guard 설정
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
다음 블록은 실제로 Guard를 등록하는 부분이고, 기본으로는 두 개가 있어요:
web이라는 이름의 Guard. session driver가 SessionGuard를 움직여 실제 처리를 하고, 사용자 객체의 제공자는users모듈이다.api라는 이름의 Guard. token driver가 TokenGuard를 움직여 실제 처리를 하고, 사용자 객체의 제공자는users모듈이다.
사용자 객체 제공 모듈
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
그다음 블록에서 등록하는 게 사용자 객체 제공 모듈이에요. 주석 처리된 것까지 포함해 두 종류가 있어요:
users라는 이름으로, eloquent driver가 Eloquent를 움직이는 모듈.- 아니면 database driver가 Database 직접 연결을 움직이는 모듈.
driver 아래에 있는 다른 설정(model이나 table 등)은 각 driver를 위한 커스텀 파라미터라, 일단 무시해도 괜찮아요.
Lumen으로 돌아가기
Laravel 쪽 설정 파일을 봤으니, Lumen의 config/auth.php 내용으로 돌아가 볼게요:
'defaults' => [
'guard' => env('AUTH_GUARD', 'api'),
],
'guards' => [
'api' => ['driver' => 'api'],
],
'providers' => [
//
],
정말 너무 덜어냈다고 생각하지 않나요?
Laravel과 비교해서 늘어난 건, .env 파일에서 Guard 할당을 가져오는 호출 정도예요(그리고 기본값은 api라는 Guard가 되고요).
한 가지 조심할 점은, Lumen은 'driver' => 'api'라고 설정하고 있지만, 실은 시스템 안에 ApiGuard 같은 건 존재하지 않는다는 거예요. api driver가 움직이는 건 RequestGuard를 기반으로 한 살짝 커스터마이즈한 버전이에요. 조금 복잡하죠? 괜찮아요, 뒤에서 하나씩 설명해 나갈게요.
정리
두 설정 파일에서, 몇몇 등장인물이 있다는 걸 대략 볼 수 있어요:
- Named Guard:
xxx라는 이름의 Guard. driver와 provider 두 부분으로 이루어진다. - Guard Driver: 실제 Guard를 움직이는 드라이버.
- Named Provider:
xxx라는 이름의 Provider(User Provider). driver와 다른 파라미터로 이루어진다. - Provider Driver: 실제 User Provider를 움직이는 드라이버.
기본 인증 아키텍처
앞의 설정 파일 설명과 정리에서, 이런 관계도를 그릴 수 있어요.

어떤 XXX Guard가 설정되고 활성화되면, 그것은 GuardDriver 한 세트를 통해 어떤 Guard를 움직이고, 그 Guard 안에서 인증 등의 처리를 해요. 게다가 XXX Guard 자신도 XXX Provider 한 세트를 정의하고, 지정된 ProviderDriver를 통해 어떤 UserProvider를 움직여요.
그럼 이 XXX Guard는 아키텍처 안에서 어떻게 쓰일까요? 그 앞뒤에 있는 두 중요한 등장인물을 그림에 더해 둘게요.

실제로 Lumen은 AuthManager를 통해 쓸 수 있는 Guard + User 조합을 가져와서 인증 등의 판단을 해요. 그리고 어떤 Guard/User를 쓸 수 있는지는 config/auth.php 안에서 정의되고 규정돼 있어요. 그러니까 직접 Guard/Driver/Provider를 더할 때는, 설정 파일에 대응하는 설정을 써 넣는 걸 꼭 잊지 마세요. 그러지 않으면 시스템이 그 커스텀 부분을 제대로 쓰지 못해요.
맺음말
여기까지 오면서 아키텍처의 전체 그림은 거의 다 보이기 시작했어요. 그 아래에서 실제로 객체가 어떻게 움직이는지, 흐름의 세부가 어떻게 도는지는, 다음 글에서 이 등장인물들과 인터페이스 타입까지 파고들어 살펴볼게요.


