Skip to main content

인증과 인가의 차이

인증(Authentication) 은 사용자가 “누구인가”를 확인합니다. 로그인 처리가 그 대표입니다. 인가(Authorization) 는 그 사용자가 “무엇을 할 수 있는가”를 판단합니다. 예를 들어 자신의 게시글만 편집할 수 있고, 관리자만 설정을 변경할 수 있는 것과 같은 제어입니다. 인증으로 로그인 기능을 구현했다면 다음 단계가 인가입니다.
Laravel의 인가 기능은 게이트(Gates)와 폴리시(Policies)의 두 가지 접근 방식을 제공합니다. 어느 쪽을 사용할지는 유스케이스에 따라 판단합니다.
사용 구분의 기준

게이트(Gates)

게이트는 클로저 기반의 단순한 인가 체크입니다. 특정 모델에 얽매이지 않는 권한 판정에 적합합니다.

Gate에 의한 인가 플로우

게이트 정의

게이트는 App\Providers\AppServiceProviderboot 메서드 내에서 Gate::define()을 사용해 정의합니다.
게이트의 클로저는 항상 첫 번째 인수로 현재 인증 중인 사용자를 받습니다. 두 번째 인수 이후에 대상 모델 등 추가 정보를 전달할 수 있습니다.

게이트로 권한 확인

컨트롤러에서 게이트를 사용해 권한을 확인하려면 Gate::allows() 또는 Gate::denies()를 사용합니다.

Gate::authorize()로 예외 발생

권한이 없는 경우 자동으로 403 응답을 반환하려면 Gate::authorize()를 사용합니다. abort(403)을 쓰는 수고가 줄어듭니다.
Gate::authorize()는 권한이 없는 경우 Illuminate\Auth\Access\AuthorizationException을 던집니다. Laravel은 이를 자동으로 403 HTTP 응답으로 변환합니다.

관리자 우회(before 메서드)

관리자 사용자에게 모든 권한을 부여하고 싶은 경우 Gate::before()를 사용합니다.
before의 클로저가 null 이외의 값을 반환하면 그 결과가 최종적인 권한 판정이 됩니다. null을 반환하거나 아무것도 반환하지 않는 경우 일반적인 게이트 판정으로 진행합니다.

Blade 템플릿에서의 @can / @cannot

템플릿에서 게이트 판정을 사용하려면 @can@cannot 디렉티브가 편리합니다.

폴리시(Policies)

폴리시는 특정 모델에 관련된 인가 로직을 클래스로 정리한 것입니다. Post 모델에 대한 작성·열람·편집·삭제의 권한 관리에는 게이트보다 폴리시가 적합합니다.

Policy에 의한 인가 플로우

폴리시 생성

make:policy Artisan 명령어로 폴리시 클래스를 생성합니다.
모델에 대응하는 CRUD 메서드를 모두 포함하는 골격을 생성하려면 --model 옵션을 사용합니다.
app/Policies/PostPolicy.php가 생성됩니다.

모델과 폴리시의 자동 검출

Laravel은 기본적으로 명명 규칙에 따라 폴리시를 자동으로 검출합니다.
  • 모델: app/Models/Post.php
  • 폴리시: app/Policies/PostPolicy.php
이 명명 규칙을 지키면 폴리시의 등록 작업은 불필요합니다.
명명 규칙에 따르지 않거나 수동으로 등록하고 싶은 경우, AppServiceProviderboot 메서드에서 Gate::policy()를 사용합니다.
Laravel 13에서는 모델에 #[UsePolicy] 어트리뷰트를 붙여 선언적으로 등록할 수도 있습니다.

폴리시 메서드 구현

--model 옵션으로 생성한 폴리시에는 표준적인 CRUD 액션에 대응하는 메서드가 포함되어 있습니다.

관리자 우회(before 메서드)

폴리시에서도 before 메서드를 정의함으로써 관리자에게 모든 권한을 부여할 수 있습니다.
before 메서드는 폴리시 클래스에 대응하는 메서드가 존재하는 경우에만 호출됩니다. 예를 들어 update 메서드가 존재하지 않는 경우 before도 호출되지 않습니다.

before 콜백의 실행 순서

컨트롤러에서 폴리시 사용

authorize() 메서드

Laravel의 컨트롤러에는 authorize() 헬퍼 메서드가 있습니다(베이스 컨트롤러를 사용하지 않는 경우는 Gate::authorize()를 사용합니다).

authorizeResource()로 RESTful 폴리시 일괄 등록

authorizeResource()를 생성자에서 호출하면 컨트롤러의 각 액션에 대응하는 폴리시 메서드를 자동으로 연결합니다.
컨트롤러 액션과 폴리시 메서드의 대응 관계:
authorizeResource()를 사용하면 각 액션에 개별로 authorize()를 쓸 필요가 없어집니다. RESTful한 리소스 컨트롤러와 조합하면 특히 편리합니다.

미들웨어에서의 인가

라우트 레벨에서 인가 체크를 하려면 can 미들웨어를 사용합니다.
can 메서드를 사용한 보다 간결한 기술:

Blade 템플릿에서 폴리시 사용

폴리시를 등록하면 Blade의 @can / @cannot 디렉티브에서도 폴리시가 자동으로 사용됩니다.

실전 예시: 블로그 기사의 권한 관리

블로그 앱에서 “투고자만 자신의 기사를 편집·삭제할 수 있는” 권한을 구현하는 예시입니다.
1

폴리시를 생성

2

폴리시 메서드를 구현

3

컨트롤러에 authorizeResource() 를 추가

4

Blade 템플릿에 권한 체크를 추가

정리

  • 게이트: 특정 모델에 얽매이지 않는 단순한 권한 판정. 관리자 대시보드에의 접근이나 글로벌한 설정 변경 권한 등.
  • 폴리시: 모델에 대한 CRUD 조작의 권한 관리. Post, Order, Comment 같은 리소스별로 폴리시 클래스를 작성.
마지막 수정일 2026년 7월 13일