ADD Separate auth request url

- api uri 문자열을 AccountApiUri 클래스로 이동.
- AccountApiUri 를 interface 에서 final static 으로 변경
This commit is contained in:
JiwonDev
2021-09-26 05:16:05 +09:00
committed by Jiwon
parent 6533b75407
commit 36d67b4e45
8 changed files with 110 additions and 20 deletions

View File

@@ -1,10 +1,15 @@
package com.yam.app.account.presentation;
public interface AccountApiUri {
public final class AccountApiUri {
String REGISTER = "/api/accounts";
String EMAIL_CONFIRM = "/api/accounts/authorize";
String LOGIN = "/api/accounts/login";
String FIND_INFO = "/api/accounts/me";
String UNAUTHORIZED_REQUEST = "/api/error/UnauthorizedRequest";
private AccountApiUri() {
}
}

View File

@@ -0,0 +1,31 @@
package com.yam.app.account.infrastructure;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
public final class SessionAuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
var session = request.getSession(false);
if (session == null) {
request.setAttribute("message", "Unauthorized request");
request.getRequestDispatcher(AccountApiUri.UNAUTHORIZED_REQUEST)
.forward(request, response);
return false;
}
if (session.getAttribute(SessionManager.LOGIN_ACCOUNT) == null) {
request.setAttribute("message", "Failed fetch principal");
request.getRequestDispatcher(AccountApiUri.UNAUTHORIZED_REQUEST)
.forward(request, response);
return false;
}
return true;
}
}

View File

@@ -5,7 +5,7 @@ import javax.servlet.http.HttpSession;
public final class SessionManager {
private static final String LOGIN_ACCOUNT = "LOGIN_ACCOUNT_EMAIL";
public static final String LOGIN_ACCOUNT = "LOGIN_ACCOUNT_EMAIL";
private final HttpSession httpSession;

View File

@@ -3,13 +3,28 @@ package com.yam.app.account.infrastructure;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
private static final String[] EXCLUDE_PATHS = {
AccountApiUri.LOGIN,
AccountApiUri.EMAIL_CONFIRM,
AccountApiUri.REGISTER,
"/api/accounts/error/**"
};
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new LoginAccountMethodArgumentResolver());
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SessionAuthInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns(EXCLUDE_PATHS);
}
}

View File

@@ -0,0 +1,25 @@
package com.yam.app.account.presentation;
import com.yam.app.account.infrastructure.AccountApiUri;
import com.yam.app.common.UnauthorizedRequestException;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE
)
public final class AccountErrorApi {
@GetMapping(AccountApiUri.UNAUTHORIZED_REQUEST)
public void apiError(HttpServletRequest request) throws UnauthorizedRequestException {
throw new UnauthorizedRequestException(
Optional.ofNullable((String) request.getAttribute("message"))
.orElse("Unauthorized request"));
}
}

View File

@@ -1,10 +1,5 @@
package com.yam.app.account.integration;
import static com.yam.app.account.presentation.AccountApiUri.EMAIL_CONFIRM;
import static com.yam.app.account.presentation.AccountApiUri.FIND_INFO;
import static com.yam.app.account.presentation.AccountApiUri.LOGIN;
import static com.yam.app.account.presentation.AccountApiUri.REGISTER;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
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.MockMvcResultMatchers.jsonPath;
@@ -13,6 +8,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.setup.SharedHttpSessionConfigurer.sharedHttpSession;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yam.app.account.infrastructure.AccountApiUri;
import com.yam.app.account.presentation.LoginAccountCommand;
import com.yam.app.account.presentation.RegisterAccountCommand;
import org.junit.jupiter.api.BeforeEach;
@@ -60,7 +56,7 @@ final class AccountIntegrationTests {
command.setPassword("password!");
// Act
final var actions = mockMvc.perform(post(REGISTER)
final var actions = mockMvc.perform(post(AccountApiUri.REGISTER)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(command))

View File

@@ -1,8 +1,8 @@
package com.yam.app.account.presentation;
import static com.yam.app.account.presentation.AccountApiUri.EMAIL_CONFIRM;
import static com.yam.app.account.presentation.AccountApiUri.LOGIN;
import static com.yam.app.account.presentation.AccountApiUri.REGISTER;
import static com.yam.app.account.infrastructure.AccountApiUri.EMAIL_CONFIRM;
import static com.yam.app.account.infrastructure.AccountApiUri.LOGIN;
import static com.yam.app.account.infrastructure.AccountApiUri.REGISTER;
import static org.mockito.Mockito.doThrow;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@@ -37,6 +37,14 @@ final class AccountCommandApiTests {
@MockBean
private AccountFacade accountFacade;
private void assertThatInvalidArgumentError(ResultActions actions) throws Exception {
actions
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.data").doesNotExist())
.andExpect(jsonPath("$.message").value("Invalid argument"));
}
@Nested
@DisplayName("로그인 HTTP API")
class LoginApi {
@@ -265,12 +273,4 @@ final class AccountCommandApiTests {
}
private void assertThatInvalidArgumentError(ResultActions actions) throws Exception {
actions
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.data").doesNotExist())
.andExpect(jsonPath("$.message").value("Invalid argument"));
}
}

View File

@@ -1,6 +1,6 @@
package com.yam.app.account.presentation;
import static com.yam.app.account.presentation.AccountApiUri.FIND_INFO;
import static com.yam.app.account.infrastructure.AccountApiUri.FIND_INFO;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -9,6 +9,8 @@ import com.yam.app.account.application.AccountFacade;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
@@ -25,6 +27,22 @@ class AccountQueryApiTest {
@MockBean
private AccountFacade accountFacade;
@ParameterizedTest
@ValueSource(strings = {FIND_INFO})
@DisplayName("로그인을 하지 않은 경우 인증이 필요한 다른 URI 에 접근할 수 없다.")
void no_current_session_account_request(String uri) throws Exception {
//Act
final var actions = mockMvc.perform(get(uri)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON));
//Assert
actions
.andExpect(status().isUnauthorized())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.data").doesNotExist());
}
@Nested
@DisplayName("사용자 조회 HTTP API")
class LoginApi {