[Spring] 헤더에 쿠키를 넣었는데 안보내지는 현상

Narcoker·2023년 8월 19일
0

ErrorHandling

목록 보기
14/14

에러 상황 1

JWT를 사용한 로그인 api 에서 나타난 현상이다.
Refresh Token 은 쿠키에 넣고
Access Token 은 header에 Authorization 이름으로 클라이언트에 보내줘야한다.

Access Token 은 잘 전달 받았지만 Refresh Token 이 오지 않았다.

...
        String accessToken = JwtUtils.generateAccessToken(userClaimsDto);
        String refreshToken = JwtUtils.generateRefreshToken(userClaimsDto);

        Optional<UserAuthentication> userAuth = getUserAuthentication(userDetails, type);

        upsertRefreshTokenToDatabase(userDetails, userAuth, refreshToken);

        response.addHeader(AUTH_HEADER, TOKEN_TYPE + accessToken);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
 		response.addCookie(getRefreshTokenCookie(refreshToken)); // 쿠키 
        response.setCharacterEncoding("UTF-8");
...

    private Cookie getRefreshTokenCookie(String refreshToken) {
        Cookie cookie = new Cookie(REFRESH_TOKEN, refreshToken);
        cookie.setHttpOnly(true);
        cookie.setMaxAge(EXPIRATION);
        return cookie;
    }

원인

도메인과 경로를 지정해주지 않아서 생긴 문제이다.
찾아보니 지정해주지 않으면 디폴트 값이 지정된다고 하는데 잘 적용이 되지 않았던 것 같다.

해결방안

    private Cookie getRefreshTokenCookie(String refreshToken) {
        Cookie cookie = new Cookie(REFRESH_TOKEN, refreshToken);
        cookie.setHttpOnly(true);
        cookie.setMaxAge(EXPIRATION);
        // 추가
        cookie.setDomain("localhost"); // 도메인 설정
        cookie.setPath("/"); // 도메인의 모든 페이지 경로에 쿠키를 전송하도록 지정
        //
        return cookie;
    }

문제 상황 2

클라이언트와 서버 모두 로컬 환경일때는 제대로 동작하였다.
그러나 클라이언트를 로컬로 실행하고 서버를 배포 서버를 사용해서 테스트 해봤을 때
이전처럼 Refresh Token이 클라이언트로 전달되지 않았다.

물론 도메인을 배포한 클라이언트의 도메인으로 설정해줬다.

원인

클라이언트와 서버의 도메인이 달라서 생긴 문제이다.

쿠키의 SameSite 정책을 잘 몰랐다.

자바의 Cookie 클래스에는 SameSite 설정하는 메서드가 따로 없어서
ResponseCookie 클래스를 사용했다.

코드

SameSite를 None 으로 설정했다.
SameSite의 관한 설명은 포스팅을 하고 따로 참조하겠다.

    private ResponseCookie getRefreshTokenCookie(String refreshToken) {
        ResponseCookie cookie = ResponseCookie.from(REFRESH_TOKEN, refreshToken)
                .maxAge(EXPIRATION)
                .path("/")
                .httpOnly(true)
                .secure(true)
                .sameSite("None") // sameSite 정책을 None 으로 설정
                .build();
        return cookie;
    }

회고

[Web] 쿠키의 SameSite 과 CSRF 공격 의 일부이다.
개발 시 사용했던 브라우저는 크롬이다.
크롬 역시 SameSite 정책이 적용되어있고 기본값은 Lax 라고 한다.

토큰 재발급 요청 메서드는 Post 이다.
그래서 안됐던 것 같다.

이 정책을 잘 몰라서 문제를 해결하기 위해 급히 SameSiteNone 으로 설정했다.

보안을 위해서 백엔드 팀에게 get으로 바꾸자고 요청해볼 생각이다.

아 저는 이 프로젝트에서 프론트앤드 팀인데 이쪽 담당하신 분이 코로나에 걸리셔서
제가 오류를 해결하려고 시도해봤습니다..ㅎ

profile
열정, 끈기, 집념의 Frontend Developer

0개의 댓글