Session과 Cookie를 Rest Api에서 사용하기

오의석·2023년 5월 8일

스프링

목록 보기
16/16

1. 발생 이슈

소셜 로그인 과정을 스프링에서 동작하게 함. login Form 자체를 활성화 한 상태.
모든 로그인을 한 후 프론트 사이트로 리다이렉트를 할 때, 쿠키로 리프레시 토큰을 줄 수 있지만 헤더로는 엑세스 토큰을 줄 수 없습니다.

2. 해결 방법

프론트에서 스프링 로그인 페이지로 리다이렉트 -> 스프링에서 소셜로그인 완료 후(세션에 액세스 토큰 임시 저장) 프론트 로그인 페이지로 이동 -> 프론트 로그인 페이지에서 axios로 엑세스 토큰 달라고 함 -> 스프링에서 header에 데이터 담아서 전달.

3. 또 다른 문제

스프링은 서버에 존재. 프론트는 localhost로 테스트 진행 중.
same site 오류 발생.

4. 해결

(1) application.properties를 통해 세션 값 설정

# 쿠키의 도메인을 설정한다.
server.servlet.session.cookie.domain = 

# 쿠키의 자바스크립트 접근 여부를 설정한다.
# 기본값: false
server.servlet.session.cookie.http-only = 

# 쿠키의 최대 사용기간을 설정한다.
# 기간 접미사를 지정할 수 있다. (h, m, s)
# 기간 접미사를 지정하지 않으면 초(s)로 설정된다.
# 0으로 설정하면 쿠키의 생성 즉시 만료된다.
# -1로 설정하면 최대 수명이 없음을 의미한다.
server.servlet.session.cookie.max-age =

# 쿠키의 이름을 정의한다.
# 기본값: JSESSIONID
server.servlet.session.cookie.name = 

# 쿠키의 유효 경로를 설정한다.
# 기본값: /
server.servlet.session.cookie.path = /

# 쿠키의 허용 범위 정책을 설정한다.
# Same-Site: 도메인 + 접미사 ( github.io, naver.com )
# strict, lax, none
# - strict: Same-Site 만 허용
# - lax: strict + HTTP GET, <a>, <link> 허용
# - none: 모든 사이트에 허용
# 기본값: lax
server.servlet.session.cookie.same-site = none

# HTTPS에서 통신할지 여부를 설정한다.
# true:  HTTPS 통신에 쿠키를 보낼 수 있다.
# false: HTTPS 통신에 쿠키를 보낼 수 없다.
# 기본값: false
server.servlet.session.cookie.secure = true

# 쿠키를 브라우저가 아닌 디스크에 저장할지 여부
# true:  브라우저를 닫거나 컴퓨터를 재시작해도 남아있다.
# false: 브라우저를 닫으면 삭제된다.
# 기본값: false
server.servlet.session.persistent = 

# 세션 데이터를 저장할 디렉토리를 지정한다.
# 기본값: 없음
server.servlet.session.store-dir = 

# 세션의 만료 시간을 설정한다.
# 클라이언트가 세션에 접근할 때마다 초기화되며, 
# 접근하지 않은 상태로 아래에서 설정한 값이 지나면 삭제된다.
# 기본값: 30m
server.servlet.session.timeout = 30m

# 쿠키를 지원하지 않는 웹브라우저를 위해 만들어진 방법이다.
# 설정하지 않는다면 쿠키 값도 전달하고 URL에 JSESSIONID도 함께 전달하게된다.
# - http://localhost:8080/;jsessionid=...
# URL에 JSESSIONID를 노출시키고 싶지 않다면 cookie로 설정하면 된다.
server.servlet.session.tracking-modes = cookie

(2) 쿠키에서의 설정


        ResponseCookie cookie = ResponseCookie.from("Refresh",jsonWebToken.getRefreshToken())
                .sameSite("None")
                .secure(true)
                .path("/")
                .maxAge(REFRESH_PERIOD)
                .build();
response.addHeader("Set-Cookie",cookie.toString());

//아래꺼는 임시 세션에 넣을 액세스 토큰 값.
request.getSession().setMaxInactiveInterval(180); //second      request.getSession().setAttribute("Authorization",jsonWebToken.getAccessToken());

5. 또 다른 오류 및 해결

header에 값을 넣었지만, axios로 읽을 수 없었다.(크롬 개발자 도구의 network에서는 header에 잘 담겨 왔다.)

  • 스프링의 시큐리티에서 설정해 주었다.
    configuration.setExposedHeaders(Arrays.asList("Authorization","Sequence"));
    부분으로 해결했다.
 @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();

        //허용할 URL
//        configuration.addAllowedOrigin("*");
//        configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000","https://xyz-gen.com","https://www.xyz-gen.com"));
//        configuration.addAllowedHeader("*");
//        configuration.addAllowedOriginPattern("*");
//        //허용할 METHOD (post,get,delete,put...등등 다 허용)
//        configuration.addAllowedMethod("*");
//        // 자격증명과 함께 요청 여부 ( 내 서버가 응답할 때 json을 JS에서 처리할 수 있게 설정)
//        configuration.setAllowCredentials(true);

        configuration.setAllowCredentials(true);
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000","https://xyz-gen.com","https://www.xyz-gen.com","http://localhost:5500"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST", "PUT", "DELETE", "OPTIONS", "HEAD"));
        configuration.setExposedHeaders(Arrays.asList("Authorization","Sequence"));
        configuration.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept",
                "Authorization", "Access-Control-Allow-Credentials", "Access-Control-Allow-Headers", "Access-Control-Allow-Methods",
                "Access-Control-Allow-Origin", "Access-Control-Expose-Headers", "Access-Control-Max-Age",
                "Access-Control-Request-Headers", "Access-Control-Request-Method", "Age", "Allow", "Alternates",
                "Content-Range", "Content-Disposition", "Content-Description"));
        configuration.setMaxAge(60L);

        //custom header 설정
//        for (String key : Constants.CORS_HEADER_URIS) {
//            configuration.addAllowedHeader(key);
//            configuration.addExposedHeader(key);
//        }

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
profile
끊임없이 나아가는 사람이 되어볼게요.

0개의 댓글