Skip to content

Commit 097e836

Browse files
authored
[Feature] OAuth 로그인시 토큰 전달 방식 변경 (#286)
* feat: TokenGenerateMachine 삭제 * feat(auth): userId로 role, accessToken 조회 기능 추가 * feat(auth): 현재 액세스 토큰 기준 userInfo, accessToken 조회 엔드포인트 추가 및 개선 * feat(token): login 토큰 추가, 구조 개선 * feat(user): 유저 정보 dto 정적 팩토리 메서드 추가 * feat(user): 유저 권한 조회 기능 추가 * feat(refreshToken): 유저 아이디 기준 리프레시 토큰 조회 기능 추가 * feat(refreshToken): 유저 아이디 기준 리프레시 토큰 조회 기능 추가 * feat(cookie): 로그인 토큰 설정 기능 추가 및 로직 개선 * feat(cookie): 토큰 타입 파라미터 추가 및 로직 개선 * feat(oauth): 리디렉션 주소 변경 및 로그인 토큰 발급 추가 - 로그인이 완료되면 엑세스 토큰과 리프레시 토큰은 서버에서 관리됨. - 쿠키에는 로그인 토큰이 설정되고 이를 활용해서 엑세스 토큰을 발급받을 수 있음. * feat(token): 로그인 토큰 생성 기능 추가 및 로직 개선 * refactor(token): 메서드 네이밍 변경 * refactor(token): 메서드 네이밍 변경 * refactor: 병합 충돌 해결 * test: 인자 사용 * test(jwt): 사용하지 않는 메서드 삭제 * feat(auth): 메시지 수정 * test(user): 유저 아이디 기준 유저 권한 조회 테스트 추가 * refactor(token): 토큰 타입 명명 수정 * refactor: 코드 리뷰 반영
1 parent ab96bfb commit 097e836

27 files changed

+267
-128
lines changed

src/main/java/com/somemore/develop/controller/TokenGenerateMachine.java

Whitespace-only changes.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.somemore.global.auth.controller;
2+
3+
import com.somemore.global.auth.annotation.CurrentUser;
4+
import com.somemore.global.auth.dto.UserInfoResponseDto;
5+
import com.somemore.global.auth.jwt.domain.EncodedToken;
6+
import com.somemore.global.auth.usecase.AuthQueryUseCase;
7+
import com.somemore.global.common.response.ApiResponse;
8+
import com.somemore.user.domain.UserRole;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.http.HttpStatus;
11+
import org.springframework.web.bind.annotation.GetMapping;
12+
import org.springframework.web.bind.annotation.RequestMapping;
13+
import org.springframework.web.bind.annotation.RestController;
14+
15+
import java.util.UUID;
16+
17+
@RestController
18+
@RequiredArgsConstructor
19+
@RequestMapping("/api/auth")
20+
public class AuthController {
21+
22+
private final AuthQueryUseCase authQueryUseCase;
23+
24+
@GetMapping("/user-info")
25+
public ApiResponse<UserInfoResponseDto> getUserInfo(
26+
@CurrentUser UUID userId
27+
) {
28+
UserRole role = authQueryUseCase.getRoleByUserId(userId);
29+
30+
return ApiResponse.ok(HttpStatus.OK.value(),
31+
UserInfoResponseDto.of(userId, role),
32+
"유저 정보 응답 성공");
33+
}
34+
35+
@GetMapping("/token")
36+
public ApiResponse<String> getToken(
37+
@CurrentUser UUID userId
38+
) {
39+
EncodedToken accessToken = authQueryUseCase.getAccessTokenByUserId(userId);
40+
41+
return ApiResponse.ok(HttpStatus.OK.value(),
42+
accessToken.getValueWithPrefix(),
43+
"액세스 토큰 응답 성공");
44+
}
45+
}

src/main/java/com/somemore/global/auth/controller/UserInfoQueryController.java

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/main/java/com/somemore/global/auth/cookie/CookieService.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,19 @@
1313
public class CookieService implements CookieUseCase {
1414

1515
@Override
16-
public void setAccessToken(HttpServletResponse response, String value) {
17-
ResponseCookie cookie = generateCookie(TokenType.ACCESS, value);
16+
public void setToken(HttpServletResponse response, String value, TokenType tokenType) {
17+
ResponseCookie cookie = generateCookie(tokenType, value);
1818
response.addHeader("Set-Cookie", cookie.toString());
19-
log.info("SET_COOKIE_ACCESS_TOKEN = {}", value);
2019
}
2120

2221
@Override
2322
public void deleteAccessToken(HttpServletResponse response) {
24-
ResponseCookie cookie = generateCookie(TokenType.SIGNOUT, TokenType.SIGNOUT.name());
23+
ResponseCookie cookie = generateCookie(TokenType.SIGN_OUT, TokenType.SIGN_OUT.name());
2524
response.addHeader("Set-Cookie", cookie.toString());
26-
log.info("DELETE_COOKIE_ACCESS_TOKEN");
2725
}
2826

2927
private static ResponseCookie generateCookie(TokenType tokenType, String value) {
30-
return ResponseCookie.from(TokenType.ACCESS.name(), value)
28+
return ResponseCookie.from(TokenType.ACCESS.getDescription(), value)
3129
.domain(".somemore.site")
3230
.httpOnly(true)
3331
.secure(true)
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.somemore.global.auth.cookie;
22

3+
import com.somemore.global.auth.jwt.domain.TokenType;
34
import jakarta.servlet.http.HttpServletResponse;
45

56
public interface CookieUseCase {
6-
void setAccessToken(HttpServletResponse response, String value);
7+
8+
void setToken(HttpServletResponse response, String value, TokenType tokenType);
79

810
void deleteAccessToken(HttpServletResponse response);
911
}

src/main/java/com/somemore/global/auth/dto/UserInfoResponseDto.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.somemore.global.auth.dto;
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.somemore.user.domain.UserRole;
45
import io.swagger.v3.oas.annotations.media.Schema;
56

7+
import java.util.UUID;
8+
69
@Schema(description = "유저 정보 DTO")
710
public record UserInfoResponseDto(
811
@JsonProperty("USER_ID")
@@ -13,4 +16,7 @@ public record UserInfoResponseDto(
1316
@Schema(description = "유저 ROLE")
1417
String role
1518
) {
19+
public static UserInfoResponseDto of(UUID userId, UserRole role) {
20+
return new UserInfoResponseDto(userId.toString(), role.getAuthority());
21+
}
1622
}

src/main/java/com/somemore/global/auth/idpw/filter/IdPwAuthFilter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.somemore.global.auth.idpw.filter;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
4-
import com.somemore.global.auth.cookie.CookieUseCase;
54
import com.somemore.global.auth.jwt.domain.EncodedToken;
65
import com.somemore.global.auth.jwt.usecase.GenerateTokensOnLoginUseCase;
76
import com.somemore.user.domain.UserRole;
@@ -47,7 +46,7 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR
4746
String userId = authResult.getName();
4847
String role = extractRole(authResult);
4948
EncodedToken accessToken =
50-
generateTokensOnLoginUseCase.saveRefreshTokenAndReturnAccessToken(
49+
generateTokensOnLoginUseCase.generateAuthTokensAndReturnAccessToken(
5150
UUID.fromString(userId),
5251
UserRole.from(role));
5352

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
package com.somemore.global.auth.jwt.domain;
22

3-
import lombok.Getter;
3+
import lombok.RequiredArgsConstructor;
44

5-
@Getter
5+
import java.time.Duration;
6+
7+
@RequiredArgsConstructor
68
public enum TokenType {
7-
ACCESS(1000 * 60 * 30),
8-
REFRESH(1000 * 60 * 60 * 24 * 7),
9-
SIGNOUT(0);
9+
ACCESS(Duration.ofMinutes(30)),
10+
REFRESH(Duration.ofDays(7)),
11+
SIGN_IN(Duration.ofMinutes(1)),
12+
SIGN_OUT(Duration.ZERO);
13+
14+
private final Duration period;
1015

11-
private final int period;
16+
public String getDescription() {
17+
return this.name() + "_TOKEN";
18+
}
1219

13-
TokenType(int period) {
14-
this.period = period;
20+
public int getPeriodInMillis() {
21+
return Math.toIntExact(period.toMillis());
1522
}
1623

1724
public int getPeriodInSeconds() {
18-
return Math.toIntExact(period / 1000);
25+
return Math.toIntExact(period.getSeconds());
1926
}
2027
}

src/main/java/com/somemore/global/auth/jwt/generator/HmacJwtGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class HmacJwtGenerator implements JwtGenerator {
2323
public EncodedToken generateToken(String userId, String role, TokenType tokenType) {
2424
Claims claims = buildClaims(userId, role);
2525
Instant now = Instant.now();
26-
Instant expiration = now.plusMillis(tokenType.getPeriod());
26+
Instant expiration = now.plusMillis(tokenType.getPeriodInMillis());
2727
String uniqueId = UUID.randomUUID().toString(); // JTI
2828

2929
return new EncodedToken(Jwts.builder()

src/main/java/com/somemore/global/auth/jwt/refresh/manager/RedisRefreshTokenManager.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,26 @@
88
import lombok.RequiredArgsConstructor;
99
import org.springframework.stereotype.Service;
1010

11+
import java.util.UUID;
12+
1113
@Service
1214
@RequiredArgsConstructor
1315
public class RedisRefreshTokenManager implements RefreshTokenManager {
1416

1517
private final RefreshTokenRepository refreshTokenRepository;
1618

1719
@Override
18-
public RefreshToken findRefreshToken(EncodedToken accessToken) {
20+
public RefreshToken findRefreshTokenByAccessToken(EncodedToken accessToken) {
1921
return refreshTokenRepository.findByAccessToken(accessToken.value())
2022
.orElseThrow(() -> new JwtException(JwtErrorType.EXPIRED_TOKEN));
2123
}
2224

25+
@Override
26+
public RefreshToken findRefreshTokenByUserId(UUID userId) {
27+
return refreshTokenRepository.findByUserId(userId.toString())
28+
.orElseThrow(() -> new JwtException(JwtErrorType.EXPIRED_TOKEN));
29+
}
30+
2331
@Override
2432
public void save(RefreshToken refreshToken) {
2533
refreshTokenRepository.save(refreshToken);

0 commit comments

Comments
 (0)