❓ 왜 EventSource는 Authorization 헤더를 못 쓸까?

oversleep·2025년 6월 2일

web-development

목록 보기
20/23

실시간 알림을 구현하려고 EventSource를 썼는데,
토큰 인증이 안 돼서 401 Unauthorized 에러가 나왔다고요?

이 포스팅에서 그 이유와 해결책을 아주 쉽게 설명해드립니다.


✅ 1. 일반 HTTP 요청은 우리가 헤더를 직접 조작할 수 있다

예를 들어, fetchaxios는 요청을 보낼 때
우리가 직접 헤더를 설정할 수 있습니다.

fetch('/api/something', {
  headers: {
    Authorization: 'Bearer abc.def.ghi',
  },
});

→ 이렇게 하면 브라우저가 우리가 설정한 Authorization 헤더를 그대로 전송합니다.


❌ 2. 하지만 EventSource는 헤더를 설정할 수 없다

const source = new EventSource('/api/subscribe');

EventSource는 우리가 헤더를 넣을 수 있는 방법이 없습니다.
→ 브라우저가 내부적으로 HTTP 요청을 자동 생성하고 관리하기 때문입니다.

즉, 토큰을 헤더에 넣고 싶어도 넣을 수가 없습니다.


💥 왜 이런 제한이 있을까?

이유설명
보안 설계 상의 제한브라우저가 기본적으로 안전하게 작동하도록 설계되어 있음
SSE의 단순한 목적서버 → 클라이언트 단방향 실시간 데이터 전송에 특화됨
자동 연결 유지EventSource는 끊어지면 브라우저가 자동으로 다시 연결 (헤더를 넣기 어려움)

✅ 3. 그럼 어떻게 인증할 수 있을까?

🔹 방법 1: 쿠키 기반 인증

  • 서버가 토큰을 HTTP-Only 쿠키로 내려줌
  • 클라이언트는 withCredentials: true로 설정
  • 브라우저가 쿠키를 자동으로 붙여줌 → EventSource에서도 인증 OK
const source = new EventSource('/api/subscribe', {
  withCredentials: true,
});

✅ 가장 안전하고 정석적인 방식


🔹 방법 2: URL에 토큰을 붙이기 (개발용)

const token = localStorage.getItem('accessToken');
const source = new EventSource(`/api/subscribe?token=${token}`);
  • 백엔드는 @RequestParam token으로 인증
  • 보안상 위험 (브라우저 히스토리, 로그 등에 노출 가능)

⚠️ 테스트 용도로만 사용하고, 실서비스에서는 피해야 함


🔹 방법 3: WebSocket 사용

  • WebSocket은 연결할 때 커스텀 헤더를 넣을 수 있음
  • 인증 처리 유연하지만, 구현이 더 복잡

📦 요약 정리

항목가능 여부
axios/fetch에서 Authorization 헤더 설정✅ 가능
EventSource에서 Authorization 헤더 설정❌ 불가능
EventSource에서 인증하려면✅ 쿠키 or 쿼리 파라미터 필요

🧠 한 줄 요약

EventSource는 브라우저가 내부적으로 요청을 만들기 때문에, 우리가 헤더를 조작할 수 없고 Authorization 헤더를 넣을 수 없다.

profile
궁금한 것, 했던 것, 시행착오 그리고 기억하고 싶은 것들을 기록합니다.

0개의 댓글