[FE] Secure Cookie 설정 시, HTTP 환경에서 인증 토큰 에러
배경
인턴 업무 중, 웹프로젝트를 AWS ECS(Elastic Container Service)에 배포할 일이 있었다. Next.js 프로젝트를 Docke 이미지로 말아서 ECR(Elastic Container Registry)에 올린 후, ECS에 배포하였다. 클러스터, 태스트 설정, 보안 그룹 설정 등의 사소한 문제는 있었지만 어떻게 해결했는데.. 이번에는 배포한 Next.js 프로젝트에서 로그인 토큰이 발급되지 않는 버그가 발생했다.
혼자서 해결해보려고 3시간 가량 코드를 쳐다보고 도커 이미지를 새로 빌드하면서 테스트해봤는데.. 도통 알 수가 없었다. 알게 된건, 로그인 api 요청 시, Next.js 서버에서는 로그인 인증 정보가 담긴 쿠키를 응답으로 제대로 보내고 있었다는 것과 Next.js 클라이언트에서는 그 쿠키를 받지 못했다는 것이다. 서버에서는 보냈는데 클라이언트에서는 왜 못 보는걸까... 로컬 개발 환경에서는 어떤 문제도 없어서 더 황당했다. 사수의 도움으로 해결할 수 있었다.

HTTP Secure Cookie
결론적으로 이는 Secure 설정으로 인해, HTTP 환경에서는 쿠키를 클라이언트에서 받을 수 없던 문제였다. HTTP 환경에서 중간자 공격에 의해 쿠키가 탈취당하는 것을 방지하기 위해 Secure를 설정함으로써 해당 쿠키가 HTTPS를 통해서만 전송되도록 지정한다. HTTPS에서는 데이터를 암호화하여 전송하기 때문에 쿠키 정보가 해커에 의해 쉽게 열람되거나 변조되는 것을 막을 수 있다.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies
Using HTTP cookies - HTTP | MDN
An HTTP cookie (web cookie, browser cookie) is a small piece of data that a server sends to a user's web browser. The browser may store the cookie and send it back to the same server with later requests. Typically, an HTTP cookie is used to tell if two req
developer.mozilla.org
# Restrict access to cookies
You can ensure that cookies are sent securely and aren't accessed by unintended parties or scripts in one of two ways: with the Secure attribute and the HttpOnly attribute.
A cookie with the Secure attribute is only sent to the server with an encrypted request over the HTTPS protocol. It's never sent with unsecured HTTP (except on localhost), which means man-in-the-middle attackers can't access it easily. Insecure sites (with http: in the URL) can't set cookies with the Secure attribute. However, don't assume that Secure prevents all access to sensitive information in cookies. For example, someone with access to the client's hard disk (or JavaScript if the HttpOnly attribute isn't set) can read and modify the information.
A cookie with the HttpOnly attribute is inaccessible to the JavaScript Document.cookie API; it's only sent to the server. For example, cookies that persist in server-side sessions don't need to be available to JavaScript and should have the HttpOnly attribute. This precaution helps mitigate cross-site scripting (XSS) attacks.
Here's an example
Set-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly
iron-session
Next.js 프로젝트에서 iron-session을 사용해서 세션 기반 인증을 처리하였다. 그래서 프로젝트 내의 iron-session 설정을 다음과 같이 변경함으로써 HTTP 환경에서도 로그인 토큰을 발급할 수 있도록 수정하였다.
export const ironOptions = {
password: process.env.NEXT_PUBLIC_SESSION_PW,
cookieName: "sendy_console_cookie",
cookieOptions: {
secure: false, // 여기
path: "/",
}
};
결론
사실 웹프로젝트를 ssl 인증서를 발급받고 HTTPS로 발급하면 해결되는 문제이긴 하다. 그러나 그러려면 또 연결할 도메인을 구매해야 하고 ssl 인증서를 발급받는 과정도 여간 귀찮은 게 아니다. 기능 테스트를 하기 위해 잠깐 ECS에 배포한거라 HTTP 환경에서 처리하는 편이 수월할거라 판단했다. 다른 에러를 처리하느라 시간을 많이 뺏겨서 결과적으로 도긴개긴같긴 하지만..
테스트용이기에 임시로 HTTP에서도 토큰 발급이 가능하도록 푼 거지만, 릴리즈 시에는 HTTPS에서만 발급하도록 secure를 다시 켜놔야 한다.
예전에 배웠던 내용인데 막상 문제가 발생하니 전혀 짐작도 못했다. 이래서 기초적인 CS가 중요하다고 하는건가?