Skip to content

Commit fda83f7

Browse files
committed
refactor : 디버깅용 로그 추가 및 설정 변경
1 parent 7af0035 commit fda83f7

File tree

12 files changed

+75
-24
lines changed

12 files changed

+75
-24
lines changed

build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ dependencies {
5353

5454
annotationProcessor("org.projectlombok:lombok")
5555

56+
//json
57+
implementation("io.jsonwebtoken:jjwt-api:0.11.5")
58+
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5")
59+
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5")
60+
// json 파싱용
61+
5662
//Spring AI
5763
implementation(platform("org.springframework.ai:spring-ai-bom:1.0.0-M4"))
5864

cookies.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Netscape HTTP Cookie File
2+
# https://curl.se/docs/http-cookies.html
3+
# This file was generated by libcurl! Edit at your own risk.
4+

src/main/java/com/back/domain/user/controller/UserAuthController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ public class UserAuthController {
3434
})
3535
@PostMapping("/refresh")
3636
public RsData<RefreshTokenResDto> refreshToken(HttpServletRequest request, HttpServletResponse response) {
37-
RefreshTokenResDto refreshToken = userAuthService.refreshTokens(request, response);
37+
RefreshTokenResDto refreshTokenData = userAuthService.refreshTokens(request, response);
3838

39-
if (refreshToken != null) {
40-
return RsData.of(200, "토큰이 갱신 성공.", refreshToken);
39+
if (refreshTokenData != null) {
40+
return RsData.of(200, "토큰이 갱신 성공.", refreshTokenData);
4141
} else {
4242
return RsData.of(401, "토큰 갱신에 실패했습니다. 다시 로그인해주세요.");
4343
}

src/main/java/com/back/domain/user/service/UserAuthService.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,24 @@ public void issueTokens(HttpServletResponse response, Long userId, String email,
137137
String accessToken = jwtUtil.generateAccessToken(userId, email, nickname);
138138
String refreshToken = refreshTokenService.generateRefreshToken(userId);
139139

140+
log.debug("토큰 발급 완료 - userId: {}, accessToken: {}, refreshToken: {}", userId, accessToken, refreshToken);
141+
140142
jwtUtil.addAccessTokenToCookie(response, accessToken);
141143
jwtUtil.addRefreshTokenToCookie(response, refreshToken);
142144
}
143145

144146
public RefreshTokenResDto refreshTokens(HttpServletRequest request, HttpServletResponse response) {
145147
try {
146148
String oldRefreshToken = jwtUtil.getRefreshTokenFromCookie(request);
149+
log.debug("토큰 갱신 시도 - 받은 RefreshToken: {}", oldRefreshToken);
150+
151+
if (oldRefreshToken == null) {
152+
log.error("RefreshToken이 쿠키에서 발견되지 않음");
153+
return null;
154+
}
147155

148-
if (oldRefreshToken == null || !refreshTokenService.validateToken(oldRefreshToken)) {
156+
if (!refreshTokenService.validateToken(oldRefreshToken)) {
157+
log.error("RefreshToken 검증 실패: {}", oldRefreshToken);
149158
return null;
150159
}
151160

src/main/java/com/back/global/globalExceptionHandler/GlobalExceptionHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
import com.back.global.rsData.RsData;
66
import com.fasterxml.jackson.core.JsonProcessingException;
77
import jakarta.validation.ConstraintViolationException;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.dao.DataAccessException;
810
import org.springframework.http.HttpStatus;
911
import org.springframework.http.ResponseEntity;
1012
import org.springframework.http.converter.HttpMessageNotReadableException;
13+
import org.springframework.transaction.TransactionException;
1114
import org.springframework.validation.FieldError;
1215
import org.springframework.web.bind.MethodArgumentNotValidException;
1316
import org.springframework.web.bind.MissingRequestHeaderException;
@@ -30,6 +33,7 @@
3033
* 500: Internal Server Error
3134
*/
3235

36+
@Slf4j
3337
@RestControllerAdvice
3438
public class GlobalExceptionHandler {
3539

src/main/java/com/back/global/jwt/JwtUtil.java

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,29 @@ public class JwtUtil {
1919

2020
private final SecretKey secretKey;
2121
private final long accessTokenExpiration;
22+
private final String cookieDomain;
2223
private static final String ACCESS_TOKEN_COOKIE_NAME = "accessToken";
2324
private static final String REFRESH_TOKEN_COOKIE_NAME = "refreshToken";
2425

2526
public JwtUtil(@Value("${custom.jwt.secretKey}") String secretKey,
26-
@Value("${custom.accessToken.expirationSeconds}") long accessTokenExpiration) {
27+
@Value("${custom.accessToken.expirationSeconds}") long accessTokenExpiration,
28+
@Value("${custom.site.cookieDomain}") String cookieDomain) {
2729
this.secretKey = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
2830
this.accessTokenExpiration = accessTokenExpiration * 1000;
31+
this.cookieDomain = cookieDomain;
2932
}
3033

3134
public String generateAccessToken(Long userId, String email, String nickname) {
3235
Date now = new Date();
3336
Date expiration = new Date(now.getTime() + accessTokenExpiration);
3437

3538
return Jwts.builder()
36-
.subject(String.valueOf(userId))
39+
.setSubject(String.valueOf(userId))
3740
.claim("email", email)
3841
.claim("nickname", nickname)
39-
.issuedAt(now)
40-
.expiration(expiration)
41-
.signWith(secretKey)
42+
.setIssuedAt(now)
43+
.setExpiration(expiration)
44+
.signWith(secretKey) // javax.crypto.SecretKey 타입
4245
.compact();
4346
}
4447

@@ -48,6 +51,7 @@ public void addAccessTokenToCookie(HttpServletResponse response, String accessTo
4851
cookie.setHttpOnly(true);
4952
cookie.setSecure(false); // 개발환경에서는 false, 프로덕션에서는 true
5053
cookie.setPath("/");
54+
cookie.setDomain(cookieDomain);
5155
cookie.setMaxAge((int) (accessTokenExpiration / 1000));
5256
response.addCookie(cookie);
5357
}
@@ -58,16 +62,17 @@ public void removeAccessTokenCookie(HttpServletResponse response) {
5862
cookie.setHttpOnly(true);
5963
cookie.setSecure(false);
6064
cookie.setPath("/");
65+
cookie.setDomain(cookieDomain);
6166
cookie.setMaxAge(0);
6267
response.addCookie(cookie);
6368
}
6469

6570
public boolean validateAccessToken(String token) {
6671
try {
67-
Jwts.parser()
68-
.verifyWith(secretKey)
72+
Jwts.parserBuilder()
73+
.setSigningKey(secretKey)
6974
.build()
70-
.parseSignedClaims(token);
75+
.parseClaimsJws(token);
7176
return true;
7277
} catch (SecurityException | MalformedJwtException e) {
7378
log.error("Invalid JWT signature: {}", e.getMessage());
@@ -90,35 +95,41 @@ public String getEmailFromToken(String token) {
9095
}
9196

9297
public String getNicknameFromToken(String token) {
93-
return parseToken(token).get("nickname", String.class);
98+
return parseToken(token).get("nickname").toString();
9499
}
95100

96101
private Claims parseToken(String token) {
97-
return Jwts.parser()
98-
.verifyWith(secretKey)
102+
return Jwts.parserBuilder()
103+
.setSigningKey(secretKey)
99104
.build()
100-
.parseSignedClaims(token)
101-
.getPayload();
105+
.parseClaimsJws(token)
106+
.getBody();
102107
}
103108

104109
public void addRefreshTokenToCookie(HttpServletResponse response, String refreshToken) {
105110
Cookie cookie = new Cookie(REFRESH_TOKEN_COOKIE_NAME, refreshToken);
106111
cookie.setHttpOnly(true);
107112
cookie.setSecure(false);
108113
cookie.setPath("/");
114+
cookie.setDomain(cookieDomain);
109115
cookie.setMaxAge(60 * 60 * 24 * 30);
110116
response.addCookie(cookie);
111117
}
112118

113119
public String getRefreshTokenFromCookie(HttpServletRequest request) {
114120
Cookie[] cookies = request.getCookies();
121+
log.debug("받은 쿠키 개수: {}", cookies != null ? cookies.length : 0);
122+
115123
if (cookies != null) {
116124
for (Cookie cookie : cookies) {
125+
log.debug("쿠키 확인 - 이름: {}, 값: {}", cookie.getName(), cookie.getValue());
117126
if (REFRESH_TOKEN_COOKIE_NAME.equals(cookie.getName())) {
127+
log.debug("RefreshToken 쿠키 발견: {}", cookie.getValue());
118128
return cookie.getValue();
119129
}
120130
}
121131
}
132+
log.debug("RefreshToken 쿠키를 찾을 수 없음");
122133
return null;
123134
}
124135

@@ -127,6 +138,7 @@ public void removeRefreshTokenCookie(HttpServletResponse response) {
127138
cookie.setHttpOnly(true);
128139
cookie.setSecure(false);
129140
cookie.setPath("/");
141+
cookie.setDomain(cookieDomain);
130142
cookie.setMaxAge(0);
131143
response.addCookie(cookie);
132144
}

src/main/java/com/back/global/rq/Rq.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ public class Rq {
2525
private final HttpServletResponse resp;
2626
private final UserService userService;
2727

28-
@Value("${custom.cookie.secure:false}")
28+
@Value("${custom.cookie.secure}")
2929
private boolean cookieSecure;
3030

31+
@Value("${custom.cookie.same}")
32+
private String cookieSameSite;
33+
34+
3135
public User getActor() {
3236
return Optional.ofNullable(
3337
SecurityContextHolder
@@ -90,7 +94,7 @@ public void setCrossDomainCookie(String name, String value, int maxAge) {
9094
.path("/")
9195
.maxAge(maxAge)
9296
.secure(cookieSecure)
93-
.sameSite("None")
97+
.sameSite(cookieSameSite)
9498
.httpOnly(true)
9599
.build();
96100
resp.addHeader("Set-Cookie", cookie.toString());

src/main/java/com/back/global/security/CustomOAuth2LoginSuccessHandler.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,15 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
2828
// Access Token과 Refresh Token 발급
2929
userAuthService.issueTokens(response, securityUser.getId(), securityUser.getEmail(), securityUser.getNickname());
3030

31-
if (securityUser.isFirstLogin()) {
31+
boolean isFirstLogin = securityUser.isFirstLogin();
32+
33+
if (isFirstLogin) {
34+
// DB에서 isFirstLogin을 false로 업데이트
3235
userAuthService.setFirstLoginFalse(securityUser.getId());
36+
// 첫 로그인이므로 first-user 페이지로 리다이렉트
3337
response.sendRedirect(frontendUrl + "/login/first-user");
3438
} else {
39+
// 기존 사용자는 success 페이지로 리다이렉트
3540
response.sendRedirect(frontendUrl + "/login/success");
3641
}
3742
}

src/main/java/com/back/global/security/SecurityUser.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ public SecurityUser(
3232
Collection<? extends GrantedAuthority> authorities,
3333
Map<String, Object> attributes
3434
) {
35-
super(email, "", authorities); // OAuth2에서는 빈 패스워드
35+
super(
36+
(email != null && !email.isBlank()) ? email : String.valueOf(id), // ★★★ 핵심 수정
37+
"",
38+
authorities
39+
);
40+
41+
3642
this.id = id;
3743
this.nickname = nickname;
3844
this.email = email;

src/main/resources/application-dev.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ logging:
4141
# 쿠키 보안 설정 (HTTP 환경용)
4242
custom:
4343
cookie:
44-
secure: false
44+
secure: true
45+
same: "Lax"
4546

4647
# # AI 설정
4748
# ai:

0 commit comments

Comments
 (0)