-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
198 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
app/api/src/main/java/org/example/property/TokenProperty.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.example.property; | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
||
@ConfigurationProperties(prefix = "token") | ||
public record TokenProperty( | ||
String secretKey, | ||
Long accessTokenExpirationSeconds, | ||
Long refreshTokenExpirationSeconds | ||
) { | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
app/api/src/main/java/org/example/security/JWTGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package org.example.security; | ||
|
||
import com.auth0.jwt.JWT; | ||
import com.auth0.jwt.algorithms.Algorithm; | ||
import java.util.Date; | ||
import lombok.RequiredArgsConstructor; | ||
import org.example.property.TokenProperty; | ||
import org.example.security.dto.TokenParam; | ||
import org.example.security.dto.UserParam; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class JWTGenerator { | ||
|
||
private final TokenProperty tokenProperty; | ||
|
||
public TokenParam generate(UserParam userParam, Date from) { | ||
return TokenParam.builder() | ||
.accessToken(createAccessToken(userParam, from)) | ||
.refreshToken(createRefreshToken(userParam, from)) | ||
.build(); | ||
} | ||
|
||
private String createAccessToken(UserParam userParam, Date from) { | ||
return JWT.create().withSubject("AccessToken") | ||
.withClaim("claim", userParam.getTokenClaim()) | ||
.withExpiresAt( | ||
new Date(from.getTime() + tokenProperty.accessTokenExpirationSeconds()) | ||
).sign(Algorithm.HMAC512(tokenProperty.secretKey())); | ||
} | ||
|
||
private String createRefreshToken(UserParam userParam, Date from) { | ||
return JWT.create().withSubject("RefreshToken") | ||
.withClaim("claim", userParam.getTokenClaim()) | ||
.withExpiresAt( | ||
new Date(from.getTime() + tokenProperty.refreshTokenExpirationSeconds()) | ||
).sign(Algorithm.HMAC512(tokenProperty.secretKey())); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
app/api/src/main/java/org/example/security/dto/AuthenticatedUser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.example.security.dto; | ||
|
||
import java.util.UUID; | ||
import org.example.vo.UserRoleApiType; | ||
|
||
public record AuthenticatedUser( | ||
UUID userId, | ||
UserRoleApiType role | ||
) { | ||
|
||
} |
11 changes: 11 additions & 0 deletions
11
app/api/src/main/java/org/example/security/dto/TokenParam.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.example.security.dto; | ||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record TokenParam( | ||
String accessToken, | ||
String refreshToken | ||
) { | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
app/api/src/main/java/org/example/security/dto/UserParam.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.example.security.dto; | ||
|
||
import java.util.Map; | ||
import java.util.UUID; | ||
import org.example.vo.UserRoleApiType; | ||
|
||
public record UserParam( | ||
UUID userId, | ||
UserRoleApiType role | ||
) { | ||
|
||
public Map<String, String> getTokenClaim() { | ||
return Map.of( | ||
"userId", userId.toString(), | ||
"role", role.name() | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package org.example.vo; | ||
|
||
public enum UserRoleApiType { | ||
GUEST, USER, ADMIN | ||
} |
88 changes: 88 additions & 0 deletions
88
app/api/src/test/java/org/example/security/JWTGeneratorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package org.example.security; | ||
|
||
import com.auth0.jwt.JWT; | ||
import com.auth0.jwt.algorithms.Algorithm; | ||
import com.auth0.jwt.exceptions.TokenExpiredException; | ||
import java.util.Date; | ||
import java.util.UUID; | ||
import org.example.property.TokenProperty; | ||
import org.example.security.dto.TokenParam; | ||
import org.example.security.dto.UserParam; | ||
import org.example.vo.UserRoleApiType; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
|
||
class JWTGeneratorTest { | ||
|
||
long hour = 3600000L; | ||
long twoWeeks = 1209600000L; | ||
|
||
TokenProperty tokenProperty = new TokenProperty( | ||
"wehfiuhewiuhfhweiuhfiuwehifueiuwhfiuw", | ||
hour, | ||
twoWeeks | ||
); | ||
|
||
JWTGenerator tokenGenerator = new JWTGenerator(tokenProperty); | ||
UserParam userParam = new UserParam( | ||
UUID.randomUUID(), | ||
UserRoleApiType.USER | ||
); | ||
|
||
@Test | ||
@DisplayName("1시간 전에 생성된 AccessToken은 유효하지 않다.") | ||
void accessTokenInvalidBeforeHourAgo() { | ||
Date beforeHour = new Date(new Date().getTime() - hour); | ||
TokenParam token = tokenGenerator.generate(userParam, beforeHour); | ||
|
||
Assertions.assertThrowsExactly( | ||
TokenExpiredException.class, | ||
() -> JWT.require(Algorithm.HMAC512(tokenProperty.secretKey())) | ||
.build() | ||
.verify(token.accessToken()) | ||
); | ||
} | ||
|
||
@Test | ||
@DisplayName("1시간 내에 생성된 AccessToken은 유효하다.") | ||
void accessTokenValidAfterHourAgo() { | ||
long second = 1000L; | ||
Date beforeHourPlusSecond = new Date(new Date().getTime() - hour + second); | ||
TokenParam token = tokenGenerator.generate(userParam, beforeHourPlusSecond); | ||
|
||
Assertions.assertDoesNotThrow( | ||
() -> JWT.require(Algorithm.HMAC512(tokenProperty.secretKey())) | ||
.build() | ||
.verify(token.accessToken()) | ||
); | ||
} | ||
|
||
@Test | ||
@DisplayName("2주 전에 생성된 RefreshToken은 유효하지 않다.") | ||
void refreshTokenInvalidBeforeHourAgo() { | ||
Date beforeTwoWeeks = new Date(new Date().getTime() - twoWeeks); | ||
TokenParam token = tokenGenerator.generate(userParam, beforeTwoWeeks); | ||
|
||
Assertions.assertThrowsExactly( | ||
TokenExpiredException.class, | ||
() -> JWT.require(Algorithm.HMAC512(tokenProperty.secretKey())) | ||
.build() | ||
.verify(token.refreshToken()) | ||
); | ||
} | ||
|
||
@Test | ||
@DisplayName("2주 내에 생성된 RefreshToken은 유효하다.") | ||
void refreshTokenValidAfterHourAgo() { | ||
long second = 1000L; | ||
Date beforeTwoWeeksPlusSecond = new Date(new Date().getTime() - twoWeeks + second); | ||
TokenParam token = tokenGenerator.generate(userParam, beforeTwoWeeksPlusSecond); | ||
|
||
Assertions.assertDoesNotThrow( | ||
() -> JWT.require(Algorithm.HMAC512(tokenProperty.secretKey())) | ||
.build() | ||
.verify(token.refreshToken()) | ||
); | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
app/domain/user-domain/src/main/java/org/example/vo/UserRole.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package org.example.vo; | ||
|
||
public enum UserRole { | ||
GUEST, USER, ADMIN | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters