개발/Spring

Spring boot&React Cookie 설정 SameSite Cookie 변경된 크롬 80 쿠키 정책

JangHC 2022. 4. 6. 21:27

이전에 쿠키 설정하던게 쿠키 정책 변경으로 갑자기 작동하지 않았다.

왜 안되는지는 검색해보면 아주 잘 나와있다(귀찮아서 아님.. 잘 설명할 자신이 없기에,,)

다만, 쿠키 domain을 설정할 때, .이 2개 들어가야 한다는 조항은 없어진듯 하다.

 

spring boot 와 react에서 적용하는 방법에 대해 기술한다.

 


# cors
cors.allowed-origins=http://localhost:3000
cors.allowed-methods=GET,POST,PUT,DELETE,OPTIONS
cors.allowed-headers=*
cors.exposed-headers=Set-Cookie
cors.max-age=3600

 


#domain

mypage.domain=localhost

 

properties에 이렇게 설정해 준다.

 

gradle

implementation 'org.springframework.boot:spring-boot-starter-security'

@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final CorsProperties corsProperties;
    /*
    * Cors 설정
    * */
    @Bean
    public UrlBasedCorsConfigurationSource corsConfigurationSource() {
        UrlBasedCorsConfigurationSource corsConfigSource = new UrlBasedCorsConfigurationSource();

        CorsConfiguration corsConfig = new CorsConfiguration();
        corsConfig.setAllowedHeaders(Arrays.asList(corsProperties.getAllowedHeaders().split(",")));
        corsConfig.setAllowedMethods(Arrays.asList(corsProperties.getAllowedMethods().split(",")));
        corsConfig.setAllowedOrigins(Arrays.asList(corsProperties.getAllowedOrigins().split(",")));
        corsConfig.setExposedHeaders(Arrays.asList(corsProperties.getExposedHeaders().split(",")));
        corsConfig.setAllowCredentials(true);
        corsConfig.setMaxAge(corsConfig.getMaxAge());

        corsConfigSource.registerCorsConfiguration("/**", corsConfig);
        return corsConfigSource;
    }
}

Security Config에 cors 설정을 한다.

 

 

package com.lesserafim.utils;

import org.springframework.http.ResponseCookie;
import org.springframework.util.SerializationUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Base64;
import java.util.Optional;

public class CookieUtil {
	
    public static Optional<Cookie> getCookie(HttpServletRequest request, String name) {
        Cookie[] cookies = request.getCookies();

        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if (name.equals(cookie.getName())) {
                    return Optional.of(cookie);
                }
            }
        }
        return Optional.empty();
    }

    public static void addCookie(HttpServletResponse response, String name, String value, int maxAge, String domain) {
    	ResponseCookie cookie = ResponseCookie.from(name, value)
            	.path("/")
                .sameSite("None")
                .httpOnly(true)
                .secure(true)
                .domain(domain)
                .maxAge(maxAge)
                .build();
    	
        response.addHeader("Set-Cookie", cookie.toString());
    }

    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String name, String domain) {
        Cookie[] cookies = request.getCookies();
        
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if (name.equals(cookie.getName())) {
                	ResponseCookie rcookie = ResponseCookie.from(name, "")
                        	.path("/")
                            .sameSite("None")
                            .httpOnly(true)
                            .secure(true)
                            .domain(domain)
                            .maxAge(0)
                            .build();
                    
                    response.addHeader("Set-Cookie", rcookie.toString());
                }
            }
        }
    }

    public static String serialize(Object obj) {
        return Base64.getUrlEncoder()
                .encodeToString(SerializationUtils.serialize(obj));
    }

    public static <T> T deserialize(Cookie cookie, Class<T> cls) {
        return cls.cast(
                SerializationUtils.deserialize(
                        Base64.getUrlDecoder().decode(cookie.getValue())
                )
        );
    }

}

Cookie util 클래스 작성

 

 

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class LoginProvider {
    private String domain;
}

 

package com.lesserafim.config.security;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.lesserafim.oauth.token.LoginProvider;

@Configuration
public class LoginConfig {
    @Value("${mypage.domain}")
    private String domain;
    
    @Bean
    public LoginProvider loginProvider() {
        return new LoginProvider(domain);
    }
}
 private final LoginProvider loginProvider;
 
 CookieUtil.deleteCookie(httpRequest, httpResponse, REFRESH_TOKEN, loginProvider.getDomain());
 CookieUtil.addCookie(httpResponse, REFRESH_TOKEN, refreshToken.getToken(), cookieMaxAge, loginProvider.getDomain());

 

사용은 이렇게 하면 된다.

 

그러면 브라우저에서는 request와 response에 자동으로 cookie를 셋팅한다.