본문 바로가기
기타

[Web] Chrome 80 쿠키 SameSite 설정하기

by 태진아밴드 2020. 12. 4.

회사에서 운영하는 서비스중에 PG관련된 부분은 다날결제모듈을 사용하고있었는데,

 

새로운 결제모듈로 바꾸게 되면서 작업을 진행하는도중 이상한 현상이 발생했다.

 

결제모듈을 호출 하고나서 결과 페이지로 돌아올때 기존의 세션이 없어지는 현상이였다.

 

기존 모듈 사용할때는 없었던 현상이고 심지어 세션이 계속 사라지는게아니라 결제를 진행하면

 

어쩔때는 그대로 살아있고 어쩔때는 없어져서 새로 생성하고 이러는 상황이라 원인을 알수가 없었다.😂

 

도와주세요

스프링 시큐리티 설정문제인가 싶어서 

 

우리의 친구, 우리의 선생님 구글님께 열심히 검색을 해봤지만 비슷한 현상이 없었다...또르르....

 

이것저것 계속 찾아보다가 크롬의 문제인가 싶어서 다른 브라우저로 테스트했더니 왠걸..? 결제가 너무 잘된다..?!

 

크롬에서 관련된 이슈가 있나 찾아봤더니 Chrome 80 쿠키 SameSite 정책이 변경되었다는 글을 보게되었다.

 

심지어 제법 오래됐다..! ( 20년 2월 발표 )

 

Chrome 80 이후 버젼부터는 SameSite 속성을 명시 하지않을 경우에는 "lax"로 명시한것처럼 동작한다는 글이였다.

 

SameSite 설정에 대해 알아보면 3가지가 있다.

 

1. Strict

 - SameSite 규칙이 엄격하게 적용되는 옵션.

해당 옵션으로 설정되면 도메인이 다를 경우 쿠키를 서버로 전송하지 않는다.

 

2. Lax

 - GET 요청과 같은 특정한 경우에만 쿠키를 전송.

 

3. None

- 웹 사이트(도메인)가 다른 경우에도 쿠키를 전송한다.

 SameSite를 None으로 설정할 경우 쿠키에 암호화된 HTTPS 연결이 필요함을 나타내는 Secure 속성을 같이 설정해주어야 한다.

- HTTPS 일때만 사용 가능.

 

 

이 SameSite 설정 탓에 결제 모듈을 호출하고오면 다른 도메인으로 다녀오는 요청이라

 

결제결과 받는부분에서는 잡혀있던 JSESSIONID가 사라져서 새로 생성하는것이였다!

( 근데 랜덤하게 될때도 있고 안될때도 있는거는 이유를 모르겠다..?)

 

해결방법으로는 톰캣 자체설정으로 해결하는 방법이 있고, 또는 java단에서 Filter 처리로 설정하는 방법이 있었다.

 

먼저 java단에서 처리 하는 방법을 살펴보자.

 

[JAVA]

import org.springframework.http.HttpHeaders;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

public class CookieAttributeFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        chain.doFilter(request, response);
        addSameSite(httpServletResponse, "None");

    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    private void addSameSite(HttpServletResponse response, String sameSite) {
        Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
        boolean firstHeader = true;
        for (String header : headers) {
            if (firstHeader) {
                response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; Secure; %s", header, "SameSite=" + sameSite));
                firstHeader = false;
                continue;
            }
            response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; Secure; %s", header, "SameSite=" + sameSite));
        }
    }

}

response에서 쿠키를 꺼내서 쿠키에 secure 설정과 SameSite설정을 집어넣어 주는 방식이다.

 

해당 클래스를 구현 한 뒤 web.xml에 필터 설정을 넣어주면된다.

 

web.xml

...
<filter>
    <filter-name>cookieAttributeFilter</filter-name>
    <filter-class>클래스경로</filter-class>
</filter>
<filter-mapping>
	<filter-name>cookieAttributeFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>
...

 

 

이제 톰캣에서 설정하는 방법을 알아보자.

 

톰캣 설정은 매우 심플하다.

 

context.xml에 설정 한줄만 추가해주면된다.

 

[Tomcat]

context.xml

...
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    <!-- 쿠키설정 추가된 부분 -->
    <CookieProcessor sameSiteCookies="none" />
</Context>
...

그리고 httpOnly secure 모드를 켜기 위해서 web.xml의 세션 설정 부분에 추가 해준다.

 

web.xml

...
<session-config>
    <session-timeout>15</session-timeout>
    <!-- 쿠키옵션 추가된 부분 -->
    <cookie-config>
            <http-only>true</http-only>
            <secure>true</secure>
    </cookie-config>
</session-config>
...

 

참고로 해당설정은 Tomcat 8.5.42 버전 이상부터 설정이 가능하다.

 

운영서버 톰캣버젼이 8.0이라 필터로 처리할까 하다가 이번기회에 톰캣 버전을 9.0으로 업데이트하고 적용완료했다.

 

이런 이슈가 있었는지도 몰랐던 나의 무지함에 대해 반성해보자..😢