Compare commits
2 Commits
feature/re
...
feature/ve
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a14020dfb5 | ||
|
|
975e03b7bd |
1
server/.gitignore
vendored
1
server/.gitignore
vendored
@@ -6,7 +6,6 @@
|
|||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
HELP.md
|
HELP.md
|
||||||
bin/**
|
|
||||||
|
|
||||||
# User-specific stuff
|
# User-specific stuff
|
||||||
.idea/**/workspace.xml
|
.idea/**/workspace.xml
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
|
import Dependencies.AnnotationProcessorLib
|
||||||
|
import Dependencies.DependencyManagementLib
|
||||||
|
import Dependencies.ModuleLib
|
||||||
|
import Dependencies.RuntimeOnlyLib
|
||||||
|
import Dependencies.TestLib
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
id("org.springframework.boot") version "2.6.7"
|
id("org.springframework.boot") version Versions.SPRING_BOOT_STARTER
|
||||||
id("io.spring.dependency-management") version "1.0.11.RELEASE"
|
id("io.spring.dependency-management") version Versions.SPRING_DEPENDENCY_MANAGEMENT
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.ticketing"
|
group = "com.ticketing"
|
||||||
@@ -23,48 +29,50 @@ repositories {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
extra["springCloudVersion"] = "2021.0.3"
|
extra["springCloudVersion"] = Versions.SPRING_CLOUD
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
implementation(Dependencies.SPRING_BOOT_STARTER_DATA_JPA)
|
||||||
implementation("org.springframework.boot:spring-boot-starter-security")
|
implementation(Dependencies.SPRING_BOOT_STARTER_SECURITY)
|
||||||
implementation("org.springframework.boot:spring-boot-starter-validation")
|
implementation(Dependencies.SPRING_BOOT_STARTER_VALIDATION)
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
implementation(Dependencies.SPRING_BOOT_STARTER_WEB)
|
||||||
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
implementation(Dependencies.SPRING_BOOT_STARTER_ACTUATOR)
|
||||||
implementation("org.springframework.boot:spring-boot-starter-log4j2")
|
implementation(Dependencies.SPRING_BOOT_STARTER_LOG4J2)
|
||||||
implementation("org.projectlombok:lombok:1.18.24")
|
implementation(Dependencies.LOMBOK)
|
||||||
implementation("io.springfox:springfox-boot-starter:3.0.0")
|
implementation(Dependencies.SPRING_FOX_STARTER)
|
||||||
implementation("io.springfox:springfox-swagger-ui:3.0.0")
|
implementation(Dependencies.SWAGGER)
|
||||||
implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.4")
|
implementation(Dependencies.JASYPT_SPRING_BOOT_STARTER)
|
||||||
implementation("com.lmax:disruptor:3.4.4")
|
implementation(Dependencies.DISRUPTOR)
|
||||||
implementation("io.jsonwebtoken:jjwt-api:0.11.5")
|
implementation(Dependencies.JJWT)
|
||||||
implementation("com.googlecode.json-simple:json-simple:1.1.1")
|
implementation(Dependencies.JSON_SIMPLE)
|
||||||
implementation("org.springframework.boot:spring-boot-starter-data-redis")
|
implementation(Dependencies.SPRING_BOOT_STARTER_REDIS)
|
||||||
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
implementation(Dependencies.JSR350)
|
||||||
implementation ("org.springframework.cloud:spring-cloud-starter-config")
|
implementation(Dependencies.SPRING_CLOUD_STARTER)
|
||||||
implementation("org.springframework.cloud:spring-cloud-starter-openfeign")
|
implementation(Dependencies.SPRING_CLOUD_FEIGN)
|
||||||
|
implementation(Dependencies.MICROMETER_CORE)
|
||||||
|
implementation(Dependencies.MICROMETER_REGISTRY_PROMETHEUS)
|
||||||
|
|
||||||
modules {
|
modules {
|
||||||
module("org.springframework.boot:spring-boot-starter-logging") {
|
module(ModuleLib.SPRING_BOOT_STARTER_LOGGING) {
|
||||||
replacedBy("org.springframework.boot:spring-boot-starter-log4j2", "Use Log4j2 instead of Logback")
|
replacedBy(ModuleLib.SPRING_BOOT_STARTER_LOG4J2, "Use Log4j2 instead of Logback")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOnly("org.projectlombok:lombok")
|
compileOnly(Dependencies.LOMBOK)
|
||||||
runtimeOnly("mysql:mysql-connector-java")
|
runtimeOnly(RuntimeOnlyLib.MYSQL)
|
||||||
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5")
|
runtimeOnly(RuntimeOnlyLib.JJWT_IMPL)
|
||||||
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5")
|
runtimeOnly(RuntimeOnlyLib.JJWT_JACKSON)
|
||||||
annotationProcessor("org.projectlombok:lombok")
|
annotationProcessor(Dependencies.LOMBOK)
|
||||||
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
|
annotationProcessor(AnnotationProcessorLib.SPRING_BOOT_PROCESSOR)
|
||||||
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
|
testImplementation(TestLib.JUPITER)
|
||||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
testImplementation(TestLib.SPRING_BOOT_STARTER)
|
||||||
testImplementation("org.springframework.security:spring-security-test")
|
testImplementation(TestLib.SPRING_SECURITY)
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyManagement {
|
dependencyManagement {
|
||||||
imports {
|
imports {
|
||||||
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
|
mavenBom(DependencyManagementLib.SPRING_CLOUD)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
8
server/buildSrc/build.gradle.kts
Normal file
8
server/buildSrc/build.gradle.kts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
plugins {
|
||||||
|
`kotlin-dsl`
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
gradlePluginPortal()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
56
server/buildSrc/src/main/kotlin/Dependencies.kt
Normal file
56
server/buildSrc/src/main/kotlin/Dependencies.kt
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
object Dependencies {
|
||||||
|
|
||||||
|
const val SPRING_BOOT_STARTER_DATA_JPA = "org.springframework.boot:spring-boot-starter-data-jpa:${Versions.SPRING_BOOT_STARTER}"
|
||||||
|
const val SPRING_BOOT_STARTER_SECURITY = "org.springframework.boot:spring-boot-starter-security:${Versions.SPRING_BOOT_STARTER}"
|
||||||
|
const val SPRING_BOOT_STARTER_VALIDATION = "org.springframework.boot:spring-boot-starter-validation:${Versions.SPRING_BOOT_STARTER}"
|
||||||
|
const val SPRING_BOOT_STARTER_WEB = "org.springframework.boot:spring-boot-starter-web:${Versions.SPRING_BOOT_STARTER}"
|
||||||
|
const val SPRING_BOOT_STARTER_ACTUATOR = "org.springframework.boot:spring-boot-starter-actuator:${Versions.SPRING_BOOT_STARTER}"
|
||||||
|
const val SPRING_BOOT_STARTER_LOG4J2 = "org.springframework.boot:spring-boot-starter-log4j2:${Versions.SPRING_BOOT_STARTER}"
|
||||||
|
const val SPRING_BOOT_STARTER_REDIS = "org.springframework.boot:spring-boot-starter-data-redis:${Versions.SPRING_BOOT_STARTER}"
|
||||||
|
|
||||||
|
const val SPRING_CLOUD_STARTER = "org.springframework.cloud:spring-cloud-starter-config:${Versions.SPRING_CLOUD_STARTER}"
|
||||||
|
const val SPRING_CLOUD_FEIGN = "org.springframework.cloud:spring-cloud-starter-openfeign:${Versions.SPRING_CLOUD_STARTER}"
|
||||||
|
|
||||||
|
const val LOMBOK = "org.projectlombok:lombok:${Versions.LOMBOK}"
|
||||||
|
|
||||||
|
const val SPRING_FOX_STARTER = "io.springfox:springfox-boot-starter:${Versions.SPRING_FOX}"
|
||||||
|
const val SWAGGER = "io.springfox:springfox-swagger-ui:${Versions.SPRING_FOX}"
|
||||||
|
|
||||||
|
const val JASYPT_SPRING_BOOT_STARTER = "com.github.ulisesbocchio:jasypt-spring-boot-starter:${Versions.JASYPT}"
|
||||||
|
|
||||||
|
const val DISRUPTOR = "com.lmax:disruptor:${Versions.DISRUPTOR}"
|
||||||
|
|
||||||
|
const val JJWT = "io.jsonwebtoken:jjwt-api:${Versions.JJWT}"
|
||||||
|
const val JSON_SIMPLE = "com.googlecode.json-simple:json-simple:${Versions.JSON_SIMPLE}"
|
||||||
|
|
||||||
|
const val MICROMETER_CORE = "io.micrometer:micrometer-core:${Versions.MICROMETER}"
|
||||||
|
const val MICROMETER_REGISTRY_PROMETHEUS = "io.micrometer:micrometer-registry-prometheus:${Versions.MICROMETER}"
|
||||||
|
|
||||||
|
const val JSR350 = "com.google.code.findbugs:jsr305:${Versions.JSR350}"
|
||||||
|
|
||||||
|
object ModuleLib {
|
||||||
|
const val SPRING_BOOT_STARTER_LOGGING = "org.springframework.boot:spring-boot-starter-logging"
|
||||||
|
const val SPRING_BOOT_STARTER_LOG4J2 = "org.springframework.boot:spring-boot-starter-log4j2"
|
||||||
|
}
|
||||||
|
|
||||||
|
object RuntimeOnlyLib {
|
||||||
|
const val MYSQL = "mysql:mysql-connector-java:${Versions.MYSQL_CONNECTOR_JAVA}"
|
||||||
|
const val JJWT_IMPL = "io.jsonwebtoken:jjwt-impl:${Versions.JJWT}"
|
||||||
|
const val JJWT_JACKSON = "io.jsonwebtoken:jjwt-jackson:${Versions.JJWT}"
|
||||||
|
}
|
||||||
|
|
||||||
|
object AnnotationProcessorLib {
|
||||||
|
const val SPRING_BOOT_PROCESSOR = "org.springframework.boot:spring-boot-configuration-processor:${Versions.SPRING_BOOT_STARTER}"
|
||||||
|
}
|
||||||
|
|
||||||
|
object TestLib {
|
||||||
|
const val JUPITER = "org.junit.jupiter:junit-jupiter-api:${Versions.JUPITER}"
|
||||||
|
const val SPRING_BOOT_STARTER = "org.springframework.boot:spring-boot-starter-test:${Versions.SPRING_BOOT_STARTER}"
|
||||||
|
const val SPRING_SECURITY = "org.springframework.security:spring-security-test:${Versions.SECURITY}"
|
||||||
|
}
|
||||||
|
|
||||||
|
object DependencyManagementLib {
|
||||||
|
const val SPRING_CLOUD = "org.springframework.cloud:spring-cloud-dependencies:${Versions.SPRING_CLOUD}"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
23
server/buildSrc/src/main/kotlin/Versions.kt
Normal file
23
server/buildSrc/src/main/kotlin/Versions.kt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
object Versions {
|
||||||
|
|
||||||
|
const val SPRING_BOOT_STARTER = "2.6.7"
|
||||||
|
const val SPRING_DEPENDENCY_MANAGEMENT = "1.0.11.RELEASE"
|
||||||
|
|
||||||
|
const val SPRING_CLOUD_STARTER = "3.1.3"
|
||||||
|
const val SPRING_CLOUD = "2021.0.3"
|
||||||
|
|
||||||
|
const val MYSQL_CONNECTOR_JAVA = "8.0.28"
|
||||||
|
|
||||||
|
const val LOMBOK = "1.18.24"
|
||||||
|
const val SPRING_FOX = "3.0.0"
|
||||||
|
const val JASYPT = "3.0.4"
|
||||||
|
const val DISRUPTOR = "3.4.4"
|
||||||
|
const val JJWT = "0.11.5"
|
||||||
|
const val JSON_SIMPLE = "1.1.1"
|
||||||
|
const val MICROMETER = "1.8.5"
|
||||||
|
const val JSR350 = "3.0.2"
|
||||||
|
|
||||||
|
const val JUPITER = "5.8.1"
|
||||||
|
const val SECURITY = "5.6.3"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -49,7 +49,7 @@ class TicketLockAspectTest {
|
|||||||
|
|
||||||
assertAll(
|
assertAll(
|
||||||
() -> assertThat(result1).isNotEqualTo(result2),
|
() -> assertThat(result1).isNotEqualTo(result2),
|
||||||
() -> assertThat(unlockCount > 0).isTrue()
|
() -> assertThat(unlockCount > 1).isTrue()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.ticketing.server.user.application;
|
package com.ticketing.server.user.application;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
|
||||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
@@ -11,11 +9,8 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.ticketing.server.global.redis.RefreshRedisRepository;
|
import com.ticketing.server.global.redis.RefreshRedisRepository;
|
||||||
import com.ticketing.server.user.application.request.LoginRequest;
|
import com.ticketing.server.user.application.request.LoginRequest;
|
||||||
import com.ticketing.server.user.application.request.RefreshRequest;
|
|
||||||
import com.ticketing.server.user.application.request.SignUpRequest;
|
import com.ticketing.server.user.application.request.SignUpRequest;
|
||||||
import com.ticketing.server.user.application.response.TokenResponse;
|
|
||||||
import com.ticketing.server.user.service.interfaces.UserService;
|
import com.ticketing.server.user.service.interfaces.UserService;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
@@ -35,12 +30,8 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
class AuthControllerTest {
|
class AuthControllerTest {
|
||||||
|
|
||||||
private static final String LOGIN_URL = "/api/auth/token";
|
private static final String LOGIN_URL = "/api/auth/token";
|
||||||
private static final String REFRESH_URL = "/api/auth/refresh";
|
|
||||||
private static final String LOGOUT_URL = "/api/auth/logout";
|
|
||||||
private static final String REGISTER_URL = "/api/users";
|
private static final String REGISTER_URL = "/api/users";
|
||||||
|
|
||||||
private static final String USER_EMAIL = "ticketing@gmail.com";
|
private static final String USER_EMAIL = "ticketing@gmail.com";
|
||||||
private static final String USER_PW = "qwe123";
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
WebApplicationContext context;
|
WebApplicationContext context;
|
||||||
@@ -63,7 +54,7 @@ class AuthControllerTest {
|
|||||||
@DisplayName("로그인 인증 성공")
|
@DisplayName("로그인 인증 성공")
|
||||||
void loginSuccess() throws Exception {
|
void loginSuccess() throws Exception {
|
||||||
// given
|
// given
|
||||||
LoginRequest request = new LoginRequest(USER_EMAIL, USER_PW);
|
LoginRequest request = new LoginRequest(USER_EMAIL, "qwe123");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
ResultActions actions = mvc.perform(post(LOGIN_URL)
|
ResultActions actions = mvc.perform(post(LOGIN_URL)
|
||||||
@@ -91,69 +82,6 @@ class AuthControllerTest {
|
|||||||
.andExpect(status().isUnauthorized());
|
.andExpect(status().isUnauthorized());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("리프레쉬 토큰 발급 성공")
|
|
||||||
void refreshTokenSuccess() throws Exception {
|
|
||||||
// given
|
|
||||||
LoginRequest loginRequest = new LoginRequest(USER_EMAIL, USER_PW);
|
|
||||||
|
|
||||||
// when
|
|
||||||
// 로그인
|
|
||||||
String loginResponseBody = mvc.perform(post(LOGIN_URL)
|
|
||||||
.content(asJsonString(loginRequest))
|
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
|
||||||
.andReturn()
|
|
||||||
.getResponse()
|
|
||||||
.getContentAsString();
|
|
||||||
|
|
||||||
TokenResponse loginResponse = objectMapper.readValue(loginResponseBody, TokenResponse.class);
|
|
||||||
RefreshRequest refreshRequest = new RefreshRequest(loginResponse.getRefreshToken());
|
|
||||||
|
|
||||||
// 토큰재발급
|
|
||||||
String refreshResponseBody = mvc.perform(post(REFRESH_URL)
|
|
||||||
.content(asJsonString(refreshRequest))
|
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
|
||||||
.andReturn()
|
|
||||||
.getResponse()
|
|
||||||
.getContentAsString();
|
|
||||||
|
|
||||||
TokenResponse refreshBody = objectMapper.readValue(refreshResponseBody, TokenResponse.class);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertAll(
|
|
||||||
() -> assertThat(refreshBody.getAccessToken()).isNotEmpty(),
|
|
||||||
() -> assertThat(refreshBody.getRefreshToken()).isNotEmpty(),
|
|
||||||
() -> assertThat(loginResponse.getTokenType()).isEqualTo(refreshBody.getTokenType()),
|
|
||||||
() -> assertThat(loginResponse.getExpiresIn()).isEqualTo(refreshBody.getExpiresIn())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("로그아웃 성공")
|
|
||||||
void logoutSuccess() throws Exception {
|
|
||||||
// given
|
|
||||||
LoginRequest loginRequest = new LoginRequest(USER_EMAIL, USER_PW);
|
|
||||||
|
|
||||||
// 로그인
|
|
||||||
String loginResponseBody = mvc.perform(post(LOGIN_URL)
|
|
||||||
.content(asJsonString(loginRequest))
|
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
|
||||||
.andReturn()
|
|
||||||
.getResponse()
|
|
||||||
.getContentAsString();
|
|
||||||
|
|
||||||
TokenResponse loginResponse = objectMapper.readValue(loginResponseBody, TokenResponse.class);
|
|
||||||
String authorization = loginResponse.getTokenType() + " " + loginResponse.getAccessToken();
|
|
||||||
|
|
||||||
// 로그아웃
|
|
||||||
ResultActions actions = mvc.perform(post(LOGOUT_URL)
|
|
||||||
.header("Authorization", authorization));
|
|
||||||
|
|
||||||
// then
|
|
||||||
actions.andDo(print())
|
|
||||||
.andExpect(status().isOk());
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void init() throws Exception {
|
void init() throws Exception {
|
||||||
mvc = MockMvcBuilders
|
mvc = MockMvcBuilders
|
||||||
@@ -161,7 +89,7 @@ class AuthControllerTest {
|
|||||||
.apply(springSecurity())
|
.apply(springSecurity())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
SignUpRequest signUpRequest = new SignUpRequest("ticketing", USER_EMAIL, USER_PW, "010-1234-5678");
|
SignUpRequest signUpRequest = new SignUpRequest("ticketing", USER_EMAIL, "qwe123", "010-1234-5678");
|
||||||
|
|
||||||
mvc.perform(post(REGISTER_URL)
|
mvc.perform(post(REGISTER_URL)
|
||||||
.content(asJsonString(signUpRequest))
|
.content(asJsonString(signUpRequest))
|
||||||
@@ -174,7 +102,6 @@ class AuthControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String asJsonString(Object object) throws JsonProcessingException {
|
private String asJsonString(Object object) throws JsonProcessingException {
|
||||||
|
|
||||||
return objectMapper.writeValueAsString(object);
|
return objectMapper.writeValueAsString(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class UserControllerTest {
|
|||||||
|
|
||||||
SignUpRequest signUpRequest;
|
SignUpRequest signUpRequest;
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("회원가입 성공")
|
@DisplayName("회원가입 성공")
|
||||||
void registerSuccess() throws Exception {
|
void registerSuccess() throws Exception {
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package com.ticketing.server.user.application;
|
package com.ticketing.server.user.application;
|
||||||
|
|
||||||
import com.ticketing.server.user.application.request.LoginRequest;
|
import com.ticketing.server.user.application.request.LoginRequest;
|
||||||
import com.ticketing.server.user.application.request.RefreshRequest;
|
|
||||||
import com.ticketing.server.user.application.response.LogoutResponse;
|
import com.ticketing.server.user.application.response.LogoutResponse;
|
||||||
|
import com.ticketing.server.user.service.dto.TokenDTO;
|
||||||
import com.ticketing.server.user.application.response.TokenResponse;
|
import com.ticketing.server.user.application.response.TokenResponse;
|
||||||
import com.ticketing.server.user.service.dto.DeleteRefreshTokenDTO;
|
import com.ticketing.server.user.service.dto.DeleteRefreshTokenDTO;
|
||||||
import com.ticketing.server.user.service.dto.TokenDTO;
|
|
||||||
import com.ticketing.server.user.service.interfaces.AuthenticationService;
|
import com.ticketing.server.user.service.interfaces.AuthenticationService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -17,6 +16,7 @@ import org.springframework.security.core.userdetails.UserDetails;
|
|||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -37,8 +37,8 @@ public class AuthController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/refresh")
|
@PostMapping("/refresh")
|
||||||
public ResponseEntity<TokenResponse> refreshToken(@RequestBody RefreshRequest request) {
|
public ResponseEntity<TokenResponse> refreshToken(@RequestParam("refreshToken") String refreshToken) {
|
||||||
TokenDTO tokenDto = authenticationService.reissueTokenDto(request.getRefreshToken());
|
TokenDTO tokenDto = authenticationService.reissueTokenDto(refreshToken);
|
||||||
|
|
||||||
return ResponseEntity.status(HttpStatus.OK)
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
.headers(getHttpHeaders())
|
.headers(getHttpHeaders())
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
package com.ticketing.server.user.application.request;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class RefreshRequest {
|
|
||||||
|
|
||||||
private String refreshToken;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -2,16 +2,14 @@ package com.ticketing.server.user.application.response;
|
|||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class TokenResponse {
|
public class TokenResponse {
|
||||||
|
|
||||||
private String accessToken;
|
private final String accessToken;
|
||||||
private String refreshToken;
|
private final String refreshToken;
|
||||||
private String tokenType;
|
private final String tokenType;
|
||||||
private long expiresIn;
|
private final long expiresIn;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.ticketing.server.user.service;
|
|||||||
import com.ticketing.server.global.exception.ErrorCode;
|
import com.ticketing.server.global.exception.ErrorCode;
|
||||||
import com.ticketing.server.global.redis.RefreshRedisRepository;
|
import com.ticketing.server.global.redis.RefreshRedisRepository;
|
||||||
import com.ticketing.server.global.redis.RefreshToken;
|
import com.ticketing.server.global.redis.RefreshToken;
|
||||||
|
import com.ticketing.server.global.security.jwt.JwtProperties;
|
||||||
import com.ticketing.server.global.security.jwt.JwtProvider;
|
import com.ticketing.server.global.security.jwt.JwtProvider;
|
||||||
import com.ticketing.server.user.service.dto.DeleteRefreshTokenDTO;
|
import com.ticketing.server.user.service.dto.DeleteRefreshTokenDTO;
|
||||||
import com.ticketing.server.user.service.dto.TokenDTO;
|
import com.ticketing.server.user.service.dto.TokenDTO;
|
||||||
@@ -13,6 +14,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au
|
|||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -21,6 +23,7 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
private final RefreshRedisRepository refreshRedisRepository;
|
private final RefreshRedisRepository refreshRedisRepository;
|
||||||
|
|
||||||
private final JwtProvider jwtProvider;
|
private final JwtProvider jwtProvider;
|
||||||
|
private final JwtProperties jwtProperties;
|
||||||
private final AuthenticationManagerBuilder authenticationManagerBuilder;
|
private final AuthenticationManagerBuilder authenticationManagerBuilder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -52,7 +55,9 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public TokenDTO reissueTokenDto(String refreshToken) {
|
public TokenDTO reissueTokenDto(String bearerRefreshToken) {
|
||||||
|
String refreshToken = resolveToken(bearerRefreshToken);
|
||||||
|
|
||||||
// 토큰 검증
|
// 토큰 검증
|
||||||
jwtProvider.validateToken(refreshToken);
|
jwtProvider.validateToken(refreshToken);
|
||||||
|
|
||||||
@@ -62,7 +67,7 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
RefreshToken findTokenEntity = refreshRedisRepository.findByEmail(authentication.getName())
|
RefreshToken findTokenEntity = refreshRedisRepository.findByEmail(authentication.getName())
|
||||||
.orElseThrow(ErrorCode::throwRefreshTokenNotFound);
|
.orElseThrow(ErrorCode::throwRefreshTokenNotFound);
|
||||||
|
|
||||||
// input 토큰이 최신 토큰이 아닐 경우 예외 처리
|
// redis 토큰과 input 토큰이 일치한지 확인
|
||||||
if (!refreshToken.equals(findTokenEntity.getToken())) {
|
if (!refreshToken.equals(findTokenEntity.getToken())) {
|
||||||
throw ErrorCode.throwUnavailableRefreshToken();
|
throw ErrorCode.throwUnavailableRefreshToken();
|
||||||
}
|
}
|
||||||
@@ -89,4 +94,11 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String resolveToken(String bearerToken) {
|
||||||
|
if (StringUtils.hasText(bearerToken) && jwtProperties.hasTokenStartsWith(bearerToken)) {
|
||||||
|
return bearerToken.substring(7);
|
||||||
|
}
|
||||||
|
throw ErrorCode.throwTokenType();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,3 +28,7 @@ spring:
|
|||||||
redis:
|
redis:
|
||||||
host: 172.18.0.3
|
host: 172.18.0.3
|
||||||
port: 6379
|
port: 6379
|
||||||
|
|
||||||
|
application:
|
||||||
|
name: monitoring
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,24 @@ spring:
|
|||||||
config:
|
config:
|
||||||
import: "optional:configserver:"
|
import: "optional:configserver:"
|
||||||
|
|
||||||
|
application:
|
||||||
|
name: monitoring
|
||||||
|
|
||||||
|
management:
|
||||||
|
endpoint:
|
||||||
|
metrics:
|
||||||
|
enabled: true
|
||||||
|
prometheus:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include: health, info, metrics, prometheus
|
||||||
|
|
||||||
|
metrics:
|
||||||
|
tags:
|
||||||
|
application: ${spring.application.name}
|
||||||
|
|
||||||
jasypt:
|
jasypt:
|
||||||
encryptor:
|
encryptor:
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import com.ticketing.server.global.redis.RefreshRedisRepository;
|
|||||||
import com.ticketing.server.global.redis.RefreshToken;
|
import com.ticketing.server.global.redis.RefreshToken;
|
||||||
import com.ticketing.server.global.security.jwt.JwtProperties;
|
import com.ticketing.server.global.security.jwt.JwtProperties;
|
||||||
import com.ticketing.server.global.security.jwt.JwtProvider;
|
import com.ticketing.server.global.security.jwt.JwtProvider;
|
||||||
import com.ticketing.server.user.domain.UserGrade;
|
|
||||||
import com.ticketing.server.user.service.dto.TokenDTO;
|
import com.ticketing.server.user.service.dto.TokenDTO;
|
||||||
|
import com.ticketing.server.user.domain.UserGrade;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@@ -62,7 +62,7 @@ class AuthenticationServiceImplTest {
|
|||||||
@DisplayName("토큰 재발급 성공")
|
@DisplayName("토큰 재발급 성공")
|
||||||
void reissueAccessToken() {
|
void reissueAccessToken() {
|
||||||
// given
|
// given
|
||||||
String refreshToken = "eyJhbGciOiJIUzUxMiJ9";
|
String refreshToken = "Bearer eyJhbGciOiJIUzUxMiJ9";
|
||||||
when(jwtProvider.validateToken(any())).thenReturn(true);
|
when(jwtProvider.validateToken(any())).thenReturn(true);
|
||||||
when(jwtProvider.getAuthentication(any())).thenReturn(authenticationToken);
|
when(jwtProvider.getAuthentication(any())).thenReturn(authenticationToken);
|
||||||
when(jwtProvider.generateTokenDto(any())).thenReturn(useJwtProvider.generateTokenDto(authenticationToken));
|
when(jwtProvider.generateTokenDto(any())).thenReturn(useJwtProvider.generateTokenDto(authenticationToken));
|
||||||
|
|||||||
Reference in New Issue
Block a user