Skip to content

Commit 07d7dcb

Browse files
authored
refactor: refreshToken 쿠키에서 환경별로 Domain 설정하도록 (#450)
* chore: 주석 가독성 개선 * chore: 쿠키 관련 환경변수 추가 * feat: 리프레시 토큰 설정 클래스 생성 * refactor: 환경에 따라 쿠키를 다르게 설정하도록 * chore: 서브모듈 업데이트
1 parent e0dd5b7 commit 07d7dcb

File tree

6 files changed

+88
-7
lines changed

6 files changed

+88
-7
lines changed

src/main/java/com/example/solidconnection/auth/controller/RefreshTokenCookieManager.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
package com.example.solidconnection.auth.controller;
22

3+
import com.example.solidconnection.auth.controller.config.RefreshTokenCookieProperties;
34
import com.example.solidconnection.auth.domain.TokenType;
45
import jakarta.servlet.http.HttpServletResponse;
6+
import lombok.RequiredArgsConstructor;
57
import org.springframework.http.HttpHeaders;
68
import org.springframework.http.ResponseCookie;
79
import org.springframework.stereotype.Component;
810

911
@Component
12+
@RequiredArgsConstructor
1013
public class RefreshTokenCookieManager {
1114

1215
private static final String COOKIE_NAME = "refreshToken";
1316
private static final String PATH = "/";
14-
private static final String SAME_SITE = "Strict";
17+
18+
private final RefreshTokenCookieProperties properties;
1519

1620
public void setCookie(HttpServletResponse response, String refreshToken) {
1721
long maxAge = convertExpireTimeToCookieMaxAge(TokenType.REFRESH.getExpireTime());
1822
setRefreshTokenCookie(response, refreshToken, maxAge);
1923
}
2024

2125
private long convertExpireTimeToCookieMaxAge(long milliSeconds) {
22-
// jwt의 expireTime: millisecond, cookie의 maxAge: second
26+
// jwt의 expireTime 단위인 millisecond를 cookie의 maxAge 단위인 second로 변환
2327
return milliSeconds / 1000;
2428
}
2529

@@ -35,7 +39,8 @@ private void setRefreshTokenCookie(
3539
.secure(true)
3640
.path(PATH)
3741
.maxAge(maxAge)
38-
.sameSite(SAME_SITE)
42+
.domain(properties.cookieDomain())
43+
.sameSite(properties.sameSite())
3944
.build();
4045
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
4146
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.example.solidconnection.auth.controller.config;
2+
3+
import org.springframework.boot.context.properties.ConfigurationProperties;
4+
import org.springframework.boot.web.server.Cookie.SameSite;
5+
6+
@ConfigurationProperties(prefix = "token.refresh")
7+
public record RefreshTokenCookieProperties(
8+
String cookieDomain
9+
) {
10+
11+
public String sameSite() {
12+
if (isDomainSet()) {
13+
return SameSite.STRICT.attributeValue(); // 도메인을 지정한 경우 SameSite=Strict
14+
}
15+
return SameSite.NONE.attributeValue(); // 도메인을 지정하지 않은 경우 SameSite=None
16+
}
17+
18+
private boolean isDomainSet() {
19+
return cookieDomain != null && !cookieDomain.isBlank();
20+
}
21+
}

src/main/resources/secret

src/test/java/com/example/solidconnection/auth/controller/RefreshTokenCookieManagerTest.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,35 @@
22

33
import static org.assertj.core.api.Assertions.assertThat;
44
import static org.junit.jupiter.api.Assertions.assertAll;
5+
import static org.mockito.BDDMockito.given;
56

7+
import com.example.solidconnection.auth.controller.config.RefreshTokenCookieProperties;
68
import com.example.solidconnection.auth.domain.TokenType;
9+
import com.example.solidconnection.support.TestContainerSpringBootTest;
710
import org.junit.jupiter.api.BeforeEach;
811
import org.junit.jupiter.api.DisplayName;
912
import org.junit.jupiter.api.Test;
13+
import org.springframework.beans.factory.annotation.Autowired;
14+
import org.springframework.boot.test.mock.mockito.MockBean;
1015
import org.springframework.mock.web.MockHttpServletResponse;
1116

1217
@DisplayName("리프레시 토큰 쿠키 매니저 테스트")
18+
@TestContainerSpringBootTest
1319
class RefreshTokenCookieManagerTest {
1420

21+
@Autowired
1522
private RefreshTokenCookieManager cookieManager;
1623

24+
@MockBean
25+
private RefreshTokenCookieProperties refreshTokenCookieProperties;
26+
27+
private final String sameSite = "Strict";
28+
private final String domain = "example.com";
29+
1730
@BeforeEach
1831
void setUp() {
19-
cookieManager = new RefreshTokenCookieManager();
32+
given(refreshTokenCookieProperties.cookieDomain()).willReturn(domain);
33+
given(refreshTokenCookieProperties.sameSite()).willReturn(sameSite);
2034
}
2135

2236
@Test
@@ -37,7 +51,8 @@ void setUp() {
3751
() -> assertThat(header).contains("Secure"),
3852
() -> assertThat(header).contains("Path=/"),
3953
() -> assertThat(header).contains("Max-Age=" + TokenType.REFRESH.getExpireTime() / 1000),
40-
() -> assertThat(header).contains("SameSite=Strict")
54+
() -> assertThat(header).contains("Domain=" + domain),
55+
() -> assertThat(header).contains("SameSite=" + sameSite)
4156
);
4257
}
4358

@@ -58,7 +73,9 @@ void setUp() {
5873
() -> assertThat(header).contains("Secure"),
5974
() -> assertThat(header).contains("Path=/"),
6075
() -> assertThat(header).contains("Max-Age=0"),
61-
() -> assertThat(header).contains("SameSite=Strict")
76+
() -> assertThat(header).contains("SameSite=Strict"),
77+
() -> assertThat(header).contains("Domain=" + domain),
78+
() -> assertThat(header).contains("SameSite=" + sameSite)
6279
);
6380
}
6481
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.example.solidconnection.auth.controller.config;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import org.junit.jupiter.api.DisplayName;
6+
import org.junit.jupiter.api.Test;
7+
import org.springframework.boot.web.server.Cookie.SameSite;
8+
9+
@DisplayName("리프레시 토큰 쿠키 설정 테스트")
10+
class RefreshTokenCookiePropertiesTest {
11+
12+
@Test
13+
void Domain을_지정했으면_SameSite가_Strict() {
14+
// given
15+
RefreshTokenCookieProperties properties = new RefreshTokenCookieProperties("example.com");
16+
17+
// when
18+
String sameSite = properties.sameSite();
19+
20+
// then
21+
assertThat(sameSite).isEqualTo(SameSite.STRICT.attributeValue());
22+
}
23+
24+
@Test
25+
void Domain을_지정하지_않았으면_SameSite가_None() {
26+
// given
27+
RefreshTokenCookieProperties properties = new RefreshTokenCookieProperties(null);
28+
29+
// when
30+
String sameSite = properties.sameSite();
31+
32+
// then
33+
assertThat(sameSite).isEqualTo(SameSite.NONE.attributeValue());
34+
}
35+
}

src/test/resources/application.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,6 @@ cors:
8585
- "http://localhost:8080"
8686
news:
8787
default-thumbnail-url: "default-thumbnail-url"
88+
token:
89+
refresh:
90+
cookie-domain: "test.domain.com"

0 commit comments

Comments
 (0)