Skip to content

Commit

Permalink
refactor: 토큰 관련 로직을 별도의 클래스로 추상화
Browse files Browse the repository at this point in the history
  • Loading branch information
jaehee329 committed Nov 16, 2023
1 parent 7c1b8f4 commit f3a3dfe
Showing 1 changed file with 11 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
package harustudy.backend.auth.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import harustudy.backend.auth.exception.InvalidAccessTokenException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@Component
public class AesTokenProvider {

private static final String alg = "AES/CBC/PKCS5Padding";
private static final String iv = "0123456789abcdef"; // 16byte
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMddHH:mm:ssyyyy");

private final ObjectMapper objectMapper;

public String createAccessToken(Long subject, Long accessTokenExpireLength, String secretKey) {
Date now = new Date();
Date expireAt = new Date(now.getTime() + accessTokenExpireLength);
String formatted = DATE_FORMAT.format(expireAt);
String text = subject + " " + formatted;
return encrypt(text, secretKey);
String token = AccessTokenUtils.issue(objectMapper, subject, accessTokenExpireLength);
return encrypt(token, secretKey);
}

private String encrypt(String text, String secretKey) {
Expand All @@ -42,50 +40,21 @@ private String encrypt(String text, String secretKey) {
}

public Long parseSubject(String accessToken, String secretKey) {
String[] splitted = decrypt(accessToken, secretKey);
validateLength(splitted);
validateExpiration(splitted);
return parseSubject(splitted);
byte[] decrypted = decrypt(accessToken, secretKey);
return AccessTokenUtils.parseSubject(objectMapper, decrypted);
}

private String[] decrypt(String accessToken, String secretKey) {
private byte[] decrypt(String accessToken, String secretKey) {
try {
Cipher cipher = Cipher.getInstance(alg);
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "AES");
IvParameterSpec ivParamSpec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParamSpec);

byte[] decodedBytes = Base64.getDecoder().decode(accessToken);
byte[] decrypted = cipher.doFinal(decodedBytes);
String string = new String(decrypted, StandardCharsets.UTF_8);
return string.split(" ");
return cipher.doFinal(decodedBytes);
} catch (GeneralSecurityException | IllegalArgumentException e) {
throw new InvalidAccessTokenException();
}
}

private void validateLength(String[] splitted) {
if (splitted.length != 2) {
throw new InvalidAccessTokenException();
}
}

private void validateExpiration(String[] splitted) {
Date expireAt = parseExpirationDate(splitted);
if (expireAt.before(new Date())) {
throw new InvalidAccessTokenException();
}
}

private Date parseExpirationDate(String[] splitted) {
try {
return DATE_FORMAT.parse(splitted[1]);
} catch (ParseException e) {
throw new InvalidAccessTokenException();
}
}

private Long parseSubject(String[] splitted) {
return Long.parseLong(splitted[0]);
}
}

0 comments on commit f3a3dfe

Please sign in to comment.