직전 배포수준에서 테스트해본 결과 refresh_token이 응답에 담겨왔으나, 저장은 하지 못한 모습을 확인했습니다.
환경은 SSL이 적용된 https 서버<->클라 간의 배포수준 통신입니다.

해결을 위해, 제가 ai-ght 개인 프로젝트를 하며 서로 다른 도메인 간 어떻게 쿠키를 주고받을 지 고민했던 내용을 반영합니다.
samesite: none 설정 추가 <- 이는 보안을 위해 반드시 secure 설정과 함께 사용되어야 합니다. (개발환경 제외)domain 설정 추가, 이는 환경변수를 통해 받아옵니다. dev는 localhost, prod에선 .(ourdomain.com)을 통해 서브도메인 모두를 허용하도록 했습니다.COOKIE_DOMAIN이라는 이름의 환경변수로 관리하므로, 배포 인스턴스 서버에 의 환경변수 파일에도 이를 반영했습니다.
async setCookieWithRefreshToken(res: any, refresh_token: string) {
const cookieSecure = this.configService.get("COOKIE_SECURE") === "true";
// env파일 별 분기 string -> boolean 변환이요!
const cookieDomain = this.configService.get("COOKIE_DOMAIN");
res.cookie("refresh_token", refresh_token, {
httpOnly: cookieSecure,
secure: cookieSecure,
domain: cookieDomain,
sameSite: "none",
maxAge: 1000 * 60 * 60 * 24 * 7,
});
return res;
}
...



위의 설정을 적용한 이후 로컬의 development환경에서this attempt to set a cookie via a Set-Cookie header was blocked because it had the "SameSite=None" attribute but did not have the "Secure" attribute, which is required in order to use "SameSite=None" 에러를 발생시키며, refresh token 저장 및 변경사항 테스트를 불가능하게 하였다.
이는 이전에 확인해본 적 있는 에러이다.
문제가 되는 부분은 쿠키 설정에서 SameSite 속성이 'None'으로 설정되어 있는데, 이 경우 Secure 속성도 반드시 true로 설정되어야 한다.
SameSite=None은 쿠키가 cross-site 요청에도 전송되어야 함을 의미하며, 이는 보안 상 문제가 될 수 있으므로 HTTPS(즉, Secure=true) 아래에서만 허용된다. 이는 이전의 ai-ght 프로젝트를 진행하며 한번 정리한 적 있는 문제로 구글의 보안 정책을 따르는 조치이다.
따라서, 개발 환경(secure=false)에서 SameSite 속성을 'Lax'로 설정하거나 Secure 속성을 false로 설정하는 것이 일반적인 조치로, 현재 우리 ganoverflow의 환경변수 분기에 따라 이를 적용하도록 수정하여 문제를 해결했다.
async setCookieWithRefreshToken(res: any, refresh_token: string) {
const cookieSecure = this.configService.get("COOKIE_SECURE") === "true"; // env파일 별 분기 string -> boolean 변환이요!
const cookieDomain = this.configService.get("COOKIE_DOMAIN");
const sameSitePolicy = cookieSecure ? "none" : "lax"; // Secure종속적 Samesite 정책!
res.cookie("refresh_token", refresh_token, {
httpOnly: cookieSecure,
secure: cookieSecure,
domain: cookieDomain,
sameSite: sameSitePolicy,
maxAge: 1000 * 60 * 60 * 24 * 7,
});
return res;
}