Skip to content

Commit

Permalink
feat: reissue token
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeongh00 committed Jul 21, 2024
1 parent d08ce34 commit b30ab27
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

import com.likelion.commonmodule.exception.jwt.SecurityCustomException;
import com.likelion.commonmodule.redis.util.RedisUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;
import com.likelion.coremodule.user.dto.LoginResponse;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -19,6 +17,7 @@
import java.util.concurrent.TimeUnit;

import static com.likelion.commonmodule.exception.jwt.SecurityErrorCode.INVALID_TOKEN;
import static com.likelion.commonmodule.exception.jwt.SecurityErrorCode.TOKEN_EXPIRED;

@Component
@Slf4j
Expand All @@ -43,37 +42,37 @@ public JwtUtil(
redisUtil = redis;
}

public String createJwtAccessToken(String nickname, String subId) {
public String createJwtAccessToken(String email, String subId) {
Instant issuedAt = Instant.now();
Instant expiration = issuedAt.plusMillis(accessExpMs);

return Jwts.builder()
.setHeaderParam("alg", "HS256")
.setHeaderParam("typ", "JWT")
.setSubject(subId)
.claim("nickname", nickname)
.claim("email", email)
.setIssuedAt(Date.from(issuedAt))
.setExpiration(Date.from(expiration))
.signWith(secretKey)
.compact();
}

public String createJwtRefreshToken(String nickname, String subId) {
public String createJwtRefreshToken(String email, String subId) {
Instant issuedAt = Instant.now();
Instant expiration = issuedAt.plusMillis(refreshExpMs);

String refreshToken = Jwts.builder()
.setHeaderParam("alg", "HS256")
.setHeaderParam("typ", "JWT")
.setSubject(subId)
.claim("nickname", nickname)
.claim("email", email)
.setIssuedAt(Date.from(issuedAt))
.setExpiration(Date.from(expiration))
.signWith(secretKey)
.compact();

redisUtil.saveAsValue(
subId + "_refresh_token",
email + "_refresh_token",
refreshToken,
refreshExpMs,
TimeUnit.MILLISECONDS
Expand All @@ -94,6 +93,28 @@ public String resolveAccessToken(HttpServletRequest request) {
return authorization.split(" ")[1];
}

public LoginResponse reissueToken(String refreshToken) {
try {
validateRefreshToken(refreshToken);
log.info("[*] Valid RefreshToken");

// 삭제 로직
String email = getEmail(refreshToken);
redisUtil.delete(email + "_refresh_token");

String subId = getSubjectFromToken(refreshToken);

return new LoginResponse(
createJwtAccessToken(email, subId),
createJwtRefreshToken(email, subId)
);
} catch (IllegalArgumentException iae) {
throw new SecurityCustomException(INVALID_TOKEN, iae);
} catch (ExpiredJwtException eje) {
throw new SecurityCustomException(TOKEN_EXPIRED, eje);
}
}

public void validateRefreshToken(String refreshToken) {
// refreshToken 유효성 검증
String email = getEmail(refreshToken);
Expand All @@ -105,6 +126,15 @@ public void validateRefreshToken(String refreshToken) {
}
}

public String getSubjectFromToken(String token) {
Claims claims = Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token)
.getBody();
return claims.getSubject();
}

public Long getId(String token) {
return Long.parseLong(getClaims(token).getSubject());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public LoginResponse kakaoLogin(final KakaoLoginRequest kakaoLoginRequest) {
final User user = userRepository.findBySubId(oidcDecodePayload.sub())
.orElseGet(() -> createNewKakaoUser(oidcDecodePayload));

return new LoginResponse(jwtUtil.createJwtAccessToken(oidcDecodePayload.nickname(), oidcDecodePayload.sub()),
jwtUtil.createJwtRefreshToken(oidcDecodePayload.nickname(), oidcDecodePayload.sub()));
return new LoginResponse(jwtUtil.createJwtAccessToken(oidcDecodePayload.email(), oidcDecodePayload.sub()),
jwtUtil.createJwtRefreshToken(oidcDecodePayload.email(), oidcDecodePayload.sub()));
}

private User createNewKakaoUser(final OidcDecodePayload oidcDecodePayload) {
Expand All @@ -38,14 +38,9 @@ private User createNewKakaoUser(final OidcDecodePayload oidcDecodePayload) {
return userRepository.save(newUser);
}

// @Transactional
// public LoginResponse reissueToken(String refreshToken) {
//
// final String token = TokenExtractUtils.extractToken(refreshToken);
// String reIssueAccessToken = attachAuthenticationType(jwtProvider::reIssueAccessToken, token);
// String reIssueRefreshToken = attachAuthenticationType(jwtProvider::reIssueRefreshToken, token);
// tokenDeleteService.deleteTokenByTokenValue(refreshToken);
//
// return new LoginResponse(reIssueAccessToken, reIssueRefreshToken);
// }
@Transactional
public LoginResponse reissueToken(String refreshToken) {

return jwtUtil.reissueToken(refreshToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.likelion.apimodule.user.dto;

public record UserInfo(String email,
String subId) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public ApplicationResponse<LoginResponse> kakaoLogin(@Valid @RequestBody KakaoLo
)
@Operation(summary = "토큰 재발급 API", description = "토큰 재발급 API입니다.")
public ApplicationResponse<String> reissue(@RequestHeader(AuthConsts.REFRESH_TOKEN_HEADER) String refreshToken) {
// LoginResponse response = loginUseCase.reissueToken(refreshToken);
LoginResponse response = loginUseCase.reissueToken(refreshToken);
return ApplicationResponse.ok("미완");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
@AllArgsConstructor
public enum UserErrorCode implements BaseErrorCode {

No_USER_INFO(HttpStatus.BAD_REQUEST, "2000", "사용자 정보가 존재하지 않습니다.");
No_USER_INFO(HttpStatus.BAD_REQUEST, "2000", "사용자 정보가 존재하지 않습니다."),
EMPTY_AUTHORIZATION_HEADER(HttpStatus.BAD_REQUEST, "2000", "토큰 정보가 비어 있습니다."),
INVALID_AUTHORIZATION_TYPE(HttpStatus.BAD_REQUEST, "2000", "타입이 유효하지 않습니다.");

private final HttpStatus httpStatus;
private final String code;
Expand Down

0 comments on commit b30ab27

Please sign in to comment.