Skip to content

Accept 헤더가 없을 때 보호 API가 JSON 401 대신 HTTP 500을 반환합니다 #46

Description

@glitter-gim

요약

보호된 API 라우트가 Accept: application/json 헤더가 없을 경우 JSON 401 대신 HTTP 500을 반환합니다.

이 과정에서 Route [login] not defined 예외가 발생합니다.

SPA/API 중심 배포에서는 web login route가 없는 경우가 많기 때문에 운영 환경에서 실제로 발생할 수 있는 문제입니다.

재현

예시:

curl -i https://example.com/api/me

결과:

HTTP/2 500
Route [login] not defined.

하지만:

curl -i -H 'Accept: application/json' https://example.com/api/me

는 정상적으로:

HTTP/2 401
content-type: application/json

를 반환합니다.

로컬에서 확인된 예시:

  • GET /api/me
  • GET /api/admin/auth/user
  • GET /api/modules/sirsoft-board/me/activity-stats

원인

Laravel의 unauthenticated redirect 흐름이 요청을 JSON 요청으로 판단하지 못할 경우 여전히 route('login') 을 시도합니다.

하지만 SPA/API 기반 환경에서는 login route 자체가 존재하지 않을 수 있습니다.

기대 동작

보호 API는 Accept 헤더 유무와 관계없이 일관되게 JSON 401을 반환해야 합니다.

login route 부재 때문에 HTTP 500이 발생하면 안 됩니다.

로컬 해결 방식

로컬에서는:

  • API guest redirect 비활성화
  • api/* 경로의 AuthenticationException을 강제로 JSON 응답 처리

방식으로 해결했으며, fake login route 추가는 하지 않았습니다.

영향

  • API 클라이언트에 따라 Accept 헤더가 항상 포함되지 않을 수 있음
  • crawler/tooling 환경에서 동작이 불안정해짐
  • downstream 운영자가 문제 회피를 위해 불필요한 login route를 추가하게 될 수 있음

관련 운영 점검 및 runtime contract 관찰은 아래 글에도 정리해 두었습니다.

https://hub.glitter.kr/board/free/54

최근 실제 운영 환경에서 API client/crawler/SPA fallback/SEO renderer가 서로 다른 계약으로 동작하던 사례들을 점검하던 흐름과 연결된 내용입니다.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions