앞서 401 Unauthorized 인증 예외 처리를 정리했다면, 이제는 다음 단계인 403 Forbidden, 즉 권한 예외 처리를 구현해보겠습니다.
“인증과 권한은 뭐가 다르지?”, “Cognito는 왜 쓰는 거지?”라는 질문이 들 수 있는데, 이 글에서 함께 정리해보겠습니다.
| 구분 | 의미 | HTTP 코드 |
|---|---|---|
| 인증 | 누구인지 확인 – 사용자인지, 로그인을 했는지 | 401 |
| 권한 | 무엇을 할 수 있는지 확인 – 관리자, 유료회원 여부 등 | 403 |
즉,
401)403)Cognito는 AWS에서 제공하는 인증 서비스입니다.
예를 들어, Lambda에서 event["requestContext"]["authorizer"] 안에 유저의 그룹, 이메일 등 정보가 담겨옵니다.
인증(401)은 이미 아래 코드로 처리하고 있다고 가정하겠습니다:
user = UserFromAuthorizer.get_user(event)
이제 유저 정보가 확인된 다음, 권한 조건을 한 줄만 추가하면 됩니다:
if not user.is_paid:
raise LambdaPermissionError("유료 사용자만 프로젝트를 생성할 수 있습니다.")
from errors import LambdaPermissionError
from utils import get_user_from_event, get_user_db_id
def handler(event, context):
try:
# 1. 인증된 사용자 추출 (401 처리 포함)
user = get_user_from_event(event)
# 2. 권한 체크 (403 처리)
if not getattr(user, "is_paid", False):
raise LambdaPermissionError("유료 사용자만 이 작업을 수행할 수 있습니다.")
# 3. 내부 사용자 ID 조회
user_id = get_user_db_id(user)
# 4. 실제 비즈니스 로직
...
return {
"statusCode": 200,
"body": "Success"
}
except Exception as e:
return handle_error(e)
from http import HTTPStatus
from errors import LambdaError # 또는 직접 정의한 베이스 에러 클래스
class LambdaPermissionError(LambdaError):
def __init__(self, message: str):
# 메시지를 꾸미지 않고 그대로 전달하고, 상태 코드만 지정
super().__init__(message, status_code=HTTPStatus.FORBIDDEN)
handle_error() 함수가 이 예외를 자동으로 받아 JSON 응답으로 변환해줍니다.
권한이 없는 사용자 (예: 게스트 그룹)는 아래와 같은 응답을 받게 됩니다:
{
"status": "Failed",
"message": "[Forbidden] 유료 사용자만 프로젝트를 생성할 수 있습니다."
}
403 Forbidden"cognito:groups": "guests" // 또는 null
위처럼 is_paid 조건이 False가 되도록 설정하면, 권한 예외를 테스트할 수 있습니다.
401은 로그인을 안 한 경우 → 인증 에러403은 로그인은 했지만 권한이 없는 경우 → 권한 에러Cognito는 사용자 인증 정보와 그룹 정보를 Lambda에 넘겨주는 브릿지 역할