Skip to content

Commit

Permalink
[#66] feat: 유효시간 duration 사용하도록 변경
Browse files Browse the repository at this point in the history
  • Loading branch information
NaMinhyeok committed Feb 6, 2025
1 parent 874fa6a commit 64f902f
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 27 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ env:
NCP_SERVER_HOST: ${{ secrets.NCP_SERVER_HOST }}
NCP_SERVER_USERNAME: ${{ secrets.NCP_SERVER_USERNAME }}
NCP_SERVER_PASSWORD: ${{ secrets.NCP_SERVER_PASSWORD }}
ACCESS_TOKEN_EXPIRATION: ${{ secrets.ACCESS_TOKEN_EXPIRATION }}
REFRESH_TOKEN_EXPIRATION: ${{ secrets.REFRESH_TOKEN_EXPIRATION }}
SSH_PORT: 22
BUILD_NUMBER: ${{ github.sha }}-${{ github.run_id }}
SPRING_PROFILES_ACTIVE: dev
Expand Down Expand Up @@ -81,6 +83,8 @@ jobs:
echo "DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}" >> .env
echo "DATABASE_ROOT_PASSWORD=${{ secrets.DATABASE_ROOT_PASSWORD }}" >> .env
echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env
echo "ACCESS_TOKEN_EXPIRATION=${{ env.ACCESS_TOKEN_EXPIRATION }}" >> .env
echo "REFRESH_TOKEN_EXPIRATION=${{ env.REFRESH_TOKEN_EXPIRATION }}" >> .env
echo "KAKAO_LOGIN_CLIENT_ID=${{ secrets.KAKAO_LOGIN_CLIENT_ID }}" >> .env
echo "KAKAO_LOGIN_CLIENT_SECRET=${{ secrets.KAKAO_LOGIN_CLIENT_SECRET }}" >> .env
echo "SPRING_PROFILES_ACTIVE=${{ env.SPRING_PROFILES_ACTIVE }}" >> .env
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.nexters.jaknaesoserver.domain.auth.model;

import io.jsonwebtoken.security.Keys;
import java.time.Duration;
import javax.crypto.SecretKey;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
Expand All @@ -9,24 +10,25 @@
@ConfigurationProperties(prefix = "jwt")
public class JwtProperties {
private final String secret;
private final Long accessTokenExpirationHours;
private final Long refreshTokenExpirationHours;
private final Duration accessTokenExpiration;
private final Duration refreshTokenExpiration;
private final SecretKey secretKey;

public JwtProperties(
String secret, Long accessTokenExpirationHours, Long refreshTokenExpirationHours) {
validateTokenExpirations(accessTokenExpirationHours, refreshTokenExpirationHours);
String secret, Duration accessTokenExpiration, Duration refreshTokenExpiration) {
validateTokenExpirations(accessTokenExpiration, refreshTokenExpiration);
this.secret = secret;
this.accessTokenExpirationHours = accessTokenExpirationHours;
this.refreshTokenExpirationHours = refreshTokenExpirationHours;
this.accessTokenExpiration = accessTokenExpiration;
this.refreshTokenExpiration = refreshTokenExpiration;
this.secretKey = Keys.hmacShaKeyFor(secret.getBytes());
}

private void validateTokenExpirations(Long accessTokenExpiration, Long refreshTokenExpiration) {
if (accessTokenExpiration <= 0 || refreshTokenExpiration <= 0) {
private void validateTokenExpirations(
Duration accessTokenExpiration, Duration refreshTokenExpiration) {
if (accessTokenExpiration.isZero() || refreshTokenExpiration.isZero()) {
throw new IllegalArgumentException("토큰의 만료시간은 0보다 커야 합니다.");
}
if (accessTokenExpiration >= refreshTokenExpiration) {
if (accessTokenExpiration.compareTo(refreshTokenExpiration) >= 0) {
throw new IllegalArgumentException("액세스 토큰의 만료시간은 리프레시 토큰의 만료시간보다 짧아야 합니다.");
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.nexters.jaknaesoserver.domain.auth.service;

import io.jsonwebtoken.Jwts;
import java.time.Duration;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import org.nexters.jaknaesoserver.domain.auth.model.JwtProperties;
import org.springframework.stereotype.Component;
Expand All @@ -15,25 +15,22 @@ public class JwtProvider {
private final JwtProperties jwtProperties;

public String generateAccessToken(final Long userId) {
return generateToken(
Map.of(), userId.toString(), jwtProperties.getAccessTokenExpirationHours());
return generateToken(Map.of(), userId.toString(), jwtProperties.getAccessTokenExpiration());
}

public String generateRefreshToken(final Long userId) {
return generateToken(
Map.of(), userId.toString(), jwtProperties.getRefreshTokenExpirationHours());
return generateToken(Map.of(), userId.toString(), jwtProperties.getRefreshTokenExpiration());
}

private String generateToken(
final Map<String, Object> claims, final String subject, final Long expirationHours) {
final Map<String, Object> claims, final String subject, final Duration expirationDuration) {
Date now = new Date();
long expirationMillis = TimeUnit.HOURS.toMillis(expirationHours);

return Jwts.builder()
.claims(claims)
.subject(subject)
.issuedAt(now)
.expiration(new Date(now.getTime() + expirationMillis))
.expiration(new Date(now.getTime() + expirationDuration.toMillis()))
.signWith(jwtProperties.getSecretKey())
.compact();
}
Expand Down
4 changes: 2 additions & 2 deletions jaknaeso-server/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ cors:

jwt:
secret: ${JWT_SECRET}
access-token-expiration-hours: 1
refresh-token-expiration-hours: 240
access-token-expiration: ${ACCESS_TOKEN_EXPIRATION:PT1M}
refresh-token-expiration: ${REFRESH_TOKEN_EXPIRATION:P30D}

oauth:
kakao:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.nexters.jaknaesoserver.domain.auth.model;

import java.time.Duration;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Expand All @@ -11,8 +12,8 @@ class JwtPropertiesTest {
void 액세스_토큰_만료시간은_0보다_커야_한다() {
// given
String secret = "thisIsTestSecretKeyShouldBeLongEnoughForHS512";
Long accessTokenExpiration = 0L;
Long refreshTokenExpiration = 36000000000L;
Duration accessTokenExpiration = Duration.ZERO;
Duration refreshTokenExpiration = Duration.ofDays(1);
// when & then
Assertions.assertThatIllegalArgumentException()
.isThrownBy(() -> new JwtProperties(secret, accessTokenExpiration, refreshTokenExpiration))
Expand All @@ -24,8 +25,8 @@ class JwtPropertiesTest {
void 리프레시_토큰_만료시간은_0보다_커야_한다() {
// given
String secret = "thisIsTestSecretKeyShouldBeLongEnoughForHS512";
Long accessTokenExpiration = 0L;
Long refreshTokenExpiration = 0L;
Duration accessTokenExpiration = Duration.ZERO;
Duration refreshTokenExpiration = Duration.ZERO;
// when & then
Assertions.assertThatIllegalArgumentException()
.isThrownBy(() -> new JwtProperties(secret, accessTokenExpiration, refreshTokenExpiration))
Expand All @@ -37,8 +38,8 @@ class JwtPropertiesTest {
void 액세스_토큰_만료시간은_리프레시_토큰_만료시간보다_짧아야_한다() {
// given
String secret = "thisIsTestSecretKeyShouldBeLongEnoughForHS512";
Long accessTokenExpiration = 1000L;
Long refreshTokenExpiration = 999L;
Duration accessTokenExpiration = Duration.ofHours(1);
Duration refreshTokenExpiration = Duration.ofHours(1);
// when & then
Assertions.assertThatIllegalArgumentException()
.isThrownBy(() -> new JwtProperties(secret, accessTokenExpiration, refreshTokenExpiration))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;

import io.jsonwebtoken.Jwts;
import java.time.Duration;
import java.util.Date;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
Expand All @@ -13,8 +14,8 @@

class JwtParserTest {
private static final String SECRET = "thisIsTestSecretKeyShouldBeLongEnoughForHS512";
private static final Long ACCESS_TOKEN_EXPIRATION = 3600000L;
private static final Long REFRESH_TOKEN_EXPIRATION = 1209600000L;
private static final Duration ACCESS_TOKEN_EXPIRATION = Duration.ofDays(1);
private static final Duration REFRESH_TOKEN_EXPIRATION = Duration.ofDays(30);

private JwtParser jwtParser;
private JwtProperties jwtProperties;
Expand Down

0 comments on commit 64f902f

Please sign in to comment.