Skip to content

Commit 8ccafdb

Browse files
committed
CLAP-84 Feat: 토큰 생성 및 관리를 담당하는 서비스 구현
<footer> - 관련: #43
1 parent 806d4c5 commit 8ccafdb

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package clap.server.application.service.auth;
2+
3+
import clap.server.adapter.outbound.jwt.access.AccessTokenClaim;
4+
import clap.server.adapter.outbound.jwt.refresh.RefreshTokenClaim;
5+
import clap.server.application.port.outbound.auth.CommandRefreshTokenPort;
6+
import clap.server.application.port.outbound.auth.JwtProvider;
7+
import clap.server.application.port.outbound.auth.LoadRefreshTokenPort;
8+
import clap.server.domain.model.auth.CustomJwts;
9+
import clap.server.domain.model.auth.RefreshToken;
10+
import clap.server.domain.model.member.Member;
11+
import clap.server.exception.JwtException;
12+
import clap.server.exception.code.AuthErrorCode;
13+
import lombok.RequiredArgsConstructor;
14+
import org.springframework.stereotype.Component;
15+
16+
import java.time.Duration;
17+
import java.time.LocalDateTime;
18+
19+
@RequiredArgsConstructor
20+
@Component
21+
public class IssueTokenService {
22+
private final JwtProvider accessTokenProvider;
23+
private final JwtProvider refreshTokenProvider;
24+
private final LoadRefreshTokenPort loadRefreshTokenPort;
25+
private final CommandRefreshTokenPort commandRefreshTokenPort;
26+
27+
public CustomJwts createToken(Member member) {
28+
String accessToken = accessTokenProvider.createToken(AccessTokenClaim.of(member.getMemberId()));
29+
String refreshToken = refreshTokenProvider.createToken(RefreshTokenClaim.of(member.getMemberId()));
30+
31+
commandRefreshTokenPort.save(
32+
RefreshToken.of(
33+
member.getMemberId(), refreshToken,
34+
toSeconds(refreshTokenProvider.getExpiredDate(refreshToken))
35+
)
36+
);
37+
38+
return CustomJwts.of(accessToken, refreshToken);
39+
}
40+
41+
private long toSeconds(LocalDateTime expiredDate) {
42+
return Duration.between(LocalDateTime.now(), expiredDate).getSeconds();
43+
}
44+
45+
public RefreshToken refresh(
46+
Long memberId,
47+
String oldRefreshToken,
48+
String newRefreshToken
49+
) throws IllegalArgumentException, IllegalStateException {
50+
RefreshToken refreshToken = loadRefreshTokenPort.findByMemberId(memberId).orElseThrow(
51+
()-> new JwtException(AuthErrorCode.REFRESH_TOKEN_NOT_FOUND)
52+
);
53+
validateToken(oldRefreshToken, refreshToken);
54+
55+
refreshToken.rotation(newRefreshToken);
56+
commandRefreshTokenPort.save(refreshToken);
57+
58+
return refreshToken;
59+
}
60+
61+
private void validateToken(String oldRefreshToken, RefreshToken refreshToken) {
62+
if (isTakenAway(oldRefreshToken, refreshToken.getToken())) {
63+
commandRefreshTokenPort.delete(refreshToken);
64+
throw new IllegalStateException("refresh token mismatched");
65+
}
66+
}
67+
68+
private boolean isTakenAway(String requestRefreshToken, String expectedRefreshToken) {
69+
return !requestRefreshToken.equals(expectedRefreshToken);
70+
}
71+
72+
}

0 commit comments

Comments
 (0)