프론트는 app.example.com, API는 api.example.com으로 도메인이 분리돼 있고요. 로그인하면 서버가 세션 쿠키를 내려주는데, 이후 요청에 그 쿠키가 안 실려서 계속 401이 납니다. fetch에 credentials: 'include'는 넣었어요.
그리고 콘솔엔 이 에러가 뜹니다.
Access to fetch at 'https://api.example.com/me' from origin 'https://app.example.com' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.서버 쪽 CORS는 편하게 Access-Control-Allow-Origin: *로 열어놨었는데, 이거랑 관련이 있어 보이긴 합니다. 프론트에서 credentials만 넣으면 될 줄 알았는데 뭘 더 맞춰야 하나요?
댓글 2
첫째, Access-Control-Allow-Origin에 *가 아니라 요청 온 정확한 오리진(https://app.example.com)을 그대로 반영해서 내려줘야 해요. 여러 오리진을 허용해야 하면 화이트리스트에서 매칭해서 그 값을 세팅하는 식으로요. 둘째, Access-Control-Allow-Credentials: true 헤더를 같이 내려줘야 브라우저가 응답을 받아들입니다. 이 두 개가 세트예요.
그런데 CORS를 다 맞춰도 쿠키가 안 실리는 두 번째 벽이 남아 있어요. 크로스 사이트에서 쿠키가 붙으려면 그 쿠키 자체가 SameSite=None; Secure로 발급돼 있어야 합니다. 지금 서버가 세션 쿠키를 Lax(기본값)로 내리고 있으면, 도메인이 다른 요청엔 브라우저가 아예 안 실어요. 그래서 Set-Cookie 할 때 SameSite=None; Secure를 반드시 붙여야 하고, Secure라서 당연히 https여야 합니다.
마지막으로 프리플라이트도 챙기세요. 인증 헤더나 커스텀 헤더가 붙으면 브라우저가 먼저 OPTIONS를 날리는데, 서버가 거기에 Allow-Methods, Allow-Headers, 그리고 위의 Allow-Credentials까지 응답해줘야 본요청이 나갑니다. 정리하면 프론트는 credentials: 'include' 하나면 되고, 나머진 전부 서버 응답 헤더와 쿠키 속성 문제예요.