origin과 site의 차이를 보여주는 비교표. 최상위 주소가 ryumaspace.com이면 댓글 서버와 origin은 다르지만 site는 같고, localhost면 origin도 site도 다르다.

·7분 읽기·업데이트:

같은 코드인데 제 컴퓨터에서만 댓글이 안 달렸습니다


댓글 서버를 다 띄우고, 블로그에 붙이는 것까지 끝냈습니다. npm run dev로 확인만 하면 되는 단계였습니다.

댓글창이 잘 떴습니다. 이름을 적고 한 줄 썼습니다. 보내기를 눌렀더니 이렇게 나왔습니다.

승인되지 않음

서버를 세 번 확인했습니다

당연히 서버를 의심했습니다.

/ping은 pong을 돌려줬습니다. 익명 로그인 설정도 켜져 있었습니다. 컨테이너 로그에는 에러가 없었습니다. 심지어 로그에 제 요청이 들어온 기록까지 남아 있었습니다. 서버는 요청을 받았고, 정상으로 처리했습니다.

그런데 브라우저는 승인이 안 됐다고 합니다.

여기서 방향을 틀었습니다. 서버가 아니라 브라우저 쪽 문제라는 뜻이니까요.

로그인은 됐는데 그다음이 안 됐습니다

댓글을 다는 과정은 두 단계입니다.

  1. 이름을 적고 “로그인” — 서버가 신분증(쿠키)을 하나 발급합니다
  2. 댓글 등록 — 그 신분증을 들고 다시 요청합니다

1번은 됐습니다. 2번에서 신분증이 서버에 도착하지 않았습니다. 서버 입장에서는 처음 보는 사람이 댓글을 달겠다고 온 겁니다. 그래서 승인이 안 됐다고 답한 거고요.

브라우저가 쿠키를 안 보내고 있었습니다.

댓글을 다는 두 단계에서 쿠키가 어디서 빠지는지. 1단계 로그인은 성공해 서버가 쿠키를 발급하지만, 2단계 댓글 등록에서 브라우저가 SameSite 규칙에 따라 그 쿠키를 빼고 보내서 서버가 처음 보는 사람으로 처리한다. 배포한 블로그에서는 같은 2단계에서 쿠키가 그대로 실려 등록된다.

same-origin과 same-site는 다릅니다

여기서 제가 헷갈리고 있던 걸 정리해야 했습니다.

브라우저에는 비슷해 보이는 두 개념이 있습니다.

origin(출처) — 프로토콜, 도메인, 포트가 전부 같아야 같은 origin입니다.
site(사이트) — 등록 가능한 도메인이 같으면 같은 site입니다. 앞에 붙는 하위 도메인은 상관없습니다. (요즘 브라우저는 http와 https도 다른 site로 봅니다.)

제 경우로 보면 이렇습니다.

최상위 주소댓글 서버originsite
ryumaspace.comcomments.ryumaspace.com다름같음
localhost:4321comments.ryumaspace.com다름다름

개발 서버에서 보든 배포된 사이트에서 보든 댓글 서버 주소는 똑같습니다. 다른 건 그걸 부르는 쪽 주소입니다. 그리고 브라우저는 그 조합을 봅니다.

쿠키에 안 적혀 있던 한 줄

그럼 왜 site가 다르면 쿠키가 안 실릴까요.

쿠키에는 SameSite라는 항목이 있습니다. 이 쿠키를 다른 사이트에서도 실어 보낼지 정하는 값입니다.

값언제 실리나
Strict같은 사이트 안에서만
Lax같은 사이트 + 링크 타고 들어오는 이동 정도
None다른 사이트에서도. 크롬·파이어폭스는 https 필수

그리고 이 값을 아예 안 적으면 어떻게 되느냐가 핵심이었습니다.

댓글 서버는 Go로 만들어졌는데, 설정 기본값이 default입니다. 이 값일 때 Go는 쿠키에 SameSite 항목을 안 적습니다. 표준 라이브러리 주석에 그렇게 적혀 있습니다.

case SameSiteDefaultMode:
	// Skip, default mode is obtained
	// by not emitting the attribute.

그리고 브라우저는 SameSite가 안 적힌 쿠키를 Lax로 취급합니다. 2020년부터 크롬이 이렇게 바꿨고, 엣지 같은 크롬 계열 브라우저가 같은 규칙을 씁니다. 파이어폭스와 사파리는 기본값이 달라서, 같은 증상이 크롬 계열에서만 날 수 있습니다.

정리하면 이렇게 됩니다.

  • 서버는 SameSite를 안 적어서 보냄
  • 브라우저는 그걸 Lax로 읽음
  • Lax니까 사이트가 다르면 안 실음
  • localhost에서 보면 사이트가 다름
  • 쿠키가 안 감 → 승인되지 않음

서드파티 쿠키 이야기가 아닙니다

여기서 한 번 더 헷갈릴 수 있는 지점이 있습니다.

크롬은 서드파티 쿠키를 없애겠다고 몇 년을 예고했다가 결국 접었습니다. 지금 크롬에서 서드파티 쿠키는 기본으로 허용됩니다.

그래서 “허용인데 왜 막히지”가 됩니다. 둘이 다른 이야기라서 그렇습니다.

  • 서드파티 쿠키 차단 — 브라우저가 사용자를 위해 켜고 끄는 설정
  • SameSite — 쿠키를 만든 서버가 직접 지정하는 값

크롬이 서드파티 쿠키를 허용해도, 서버가 Lax로 보낸 쿠키는 안 실립니다. 서버가 스스로 그렇게 정한 거니까요.

참고로 사파리는 2020년부터 서드파티 쿠키를 아예 막고 있고, 파이어폭스는 사이트별로 쿠키 저장소를 따로 씁니다. 크롬이 마음을 바꿨다고 이 문제가 사라진 게 아닙니다.

그래서 어떻게 했나

배포하고 확인했습니다.

배포된 블로그는 주소가 ryumaspace.com이고 댓글 서버는 comments.ryumaspace.com입니다. 둘 다 ryumaspace.com 아래라 같은 사이트입니다. 쿠키가 실립니다.

실제로 배포하고 나니 댓글이 그냥 달렸습니다. 서버는 처음부터 아무 문제가 없었습니다.

만약 배포한 뒤에도 같은 메시지가 나온다면 그때는 서버 쪽에서 명시적으로 지정해야 합니다.

- AUTH_SAME_SITE=none

None은 크롬 계열에서는 https에서만 동작합니다. 그리고 이건 “다른 사이트에서도 이 쿠키를 실어라”는 뜻이라 필요할 때만 켜는 게 맞습니다. 저는 안 켜도 돼서 안 켰습니다.

로컬에서 재현이 안 되는 것들

이번에 배운 건 기술 자체보다 이쪽입니다.

로컬 개발 서버는 편하지만 주소가 다릅니다. 그리고 브라우저의 상당수 규칙이 주소를 기준으로 돕니다. 쿠키, 보안 정책, 리다이렉트 허용 목록, OAuth 콜백 같은 것들이 전부 그렇습니다.

이런 기능은 로컬에서 아무리 봐도 답이 안 나옵니다. 배포 환경에서만 재현되는 종류입니다.

그래서 순서를 이렇게 잡는 게 낫습니다.

  1. 로컬에서는 화면이 뜨는 것까지만 확인한다
  2. 로그인, 쿠키, 외부 연동은 배포하고 확인한다
  3. 그때도 안 되면 그때 서버 설정을 건드린다

저는 1번에서 “댓글까지 달아보자”고 하다가 반나절을 썼습니다. 서버 설정을 세 번 바꿔가며 확인했는데, 전부 처음부터 맞는 설정이었습니다.

건드리기 전에 어디서 막힌 건지부터 봤어야 했습니다.

고친 곳

2026년 9월 29일, 글에 붙일 참고 문서를 하나씩 다시 열어보다가 본문과 어긋나는 곳을 찾아 고쳤습니다.

  • “다른 브라우저도 따라갔다”를 고쳤습니다. SameSite가 없는 쿠키를 Lax로 보는 건 크롬 계열이고, 파이어폭스와 사파리는 기본값이 다릅니다.
  • site 설명과 None 설명을 조금 더 정확하게 적었습니다.

참고한 문서


댓글

로그인도 이메일도 필요 없습니다. 이름만 적고 편하게 남겨주세요.