Skip to content

Commit 9a22aa6

Browse files
authored
[Feat]: 인증 예외 핸들링 구현 (#154)
* [Feat]: osiv 끄기 * [Feat]: HomeController * [Refactor]: 존재하지 않는 회원 Exception 추가 * [Feat]: 인증 예외 핸들링 * [Fix]: 오류 해결
1 parent 6cf1954 commit 9a22aa6

File tree

8 files changed

+53
-19
lines changed

8 files changed

+53
-19
lines changed

src/main/java/com/backend/domain/home/controller/HomeController.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.backend.domain.home.controller;
22

3-
import org.springframework.stereotype.Controller;
43
import org.springframework.web.bind.annotation.GetMapping;
54
import org.springframework.web.bind.annotation.RestController;
65

src/main/java/com/backend/domain/product/controller/ApiV1ProductController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
import com.backend.domain.product.enums.AuctionStatus;
1414
import com.backend.domain.product.enums.ProductSearchSortType;
1515
import com.backend.domain.product.enums.SaleStatus;
16+
import com.backend.domain.product.exception.ProductException;
1617
import com.backend.domain.product.mapper.ProductMapper;
1718
import com.backend.domain.product.service.ProductService;
18-
import com.backend.global.exception.ServiceException;
1919
import com.backend.global.page.dto.PageDto;
2020
import com.backend.global.response.RsData;
2121
import jakarta.validation.Valid;
@@ -140,7 +140,7 @@ public RsData<PageDto<ProductListByMemberItemDto>> getProductsByMember(
140140
@RequestParam(defaultValue = "SELLING") SaleStatus status,
141141
@RequestParam(defaultValue = "LATEST") ProductSearchSortType sort
142142
) {
143-
Member actor = memberService.findById(memberId).orElseThrow(() -> new ServiceException("404", "존재하지 않는 회원입니다"));
143+
Member actor = memberService.findById(memberId).orElseThrow(ProductException::memberNotFound);
144144

145145
Page<Product> products = productService.findByMemberPaged(page, size, sort, actor, status);
146146

src/main/java/com/backend/domain/product/exception/ProductException.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public static ProductException imageNotFound() {
2323
return notFound(2, "존재하지 않는 이미지입니다");
2424
}
2525

26+
// 일단 ProductException 에서 정의 (MemberException 생성되면 제거)
27+
public static ProductException memberNotFound() {
28+
return new ProductException(RsStatus.NOT_FOUND.getResultCode(), "존재하지 않는 회원입니다");
29+
}
30+
2631
// ======================================= forbidden ======================================= //
2732
private static ProductException forbidden(int detailCode, String msg) {
2833
return new ProductException(RsStatus.FORBIDDEN.getResultCode() + "-" + detailCode, msg);

src/main/java/com/backend/global/initdata/BaseInitData.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import com.backend.domain.bid.repository.BidRepository;
55
import com.backend.domain.member.entity.Member;
66
import com.backend.domain.member.repository.MemberRepository;
7-
import com.backend.domain.member.service.MemberService;
87
import com.backend.domain.product.entity.Product;
98
import com.backend.domain.product.repository.ProductRepository;
109
import lombok.RequiredArgsConstructor;

src/main/java/com/backend/global/security/SecurityConfig.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.backend.global.security;
22

3+
import com.backend.global.exception.ServiceException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
35
import lombok.RequiredArgsConstructor;
46
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
57
import org.springframework.context.annotation.Bean;
@@ -25,6 +27,7 @@
2527
public class SecurityConfig {
2628

2729
private final JwtAuthenticationFilter jwtAuthenticationFilter;
30+
private final ObjectMapper objectMapper;
2831

2932
@Bean
3033
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
@@ -54,7 +57,19 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
5457
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
5558
.formLogin(AbstractHttpConfigurer::disable)
5659
.httpBasic(AbstractHttpConfigurer::disable)
57-
.logout(AbstractHttpConfigurer::disable);
60+
.logout(AbstractHttpConfigurer::disable)
61+
.exceptionHandling(
62+
exception -> exception
63+
.authenticationEntryPoint((request, response, authException) -> {
64+
response.setContentType("application/json;charset=UTF-8");
65+
response.setStatus(401);
66+
response.getWriter().write(
67+
objectMapper.writeValueAsString(
68+
ServiceException.unauthorized("로그인 후 이용해주세요.")
69+
)
70+
);
71+
})
72+
);
5873
return http.build();
5974
}
6075

src/main/resources/application.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ spring:
3131
highlight_sql: true
3232
use_sql_comments: true
3333
default_batch_fetch_size: 100 # N+1 문제 해결
34+
open-in-view: false
3435

3536
data:
3637
redis:

src/test/java/com/backend/domain/member/controller/ApiV1MemberControllerTest.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,32 @@
88
import com.backend.global.redis.TestRedisConfiguration;
99
import com.fasterxml.jackson.databind.ObjectMapper;
1010
import com.jayway.jsonpath.JsonPath;
11-
import org.springframework.boot.test.mock.mockito.MockBean;
12-
import static org.mockito.ArgumentMatchers.any;
13-
import static org.mockito.BDDMockito.given;
14-
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
15-
import org.springframework.context.annotation.Import;
1611
import org.junit.jupiter.api.AfterEach;
1712
import org.junit.jupiter.api.BeforeEach;
1813
import org.junit.jupiter.api.DisplayName;
1914
import org.junit.jupiter.api.Test;
2015
import org.springframework.beans.factory.annotation.Autowired;
2116
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
2217
import org.springframework.boot.test.context.SpringBootTest;
23-
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
18+
import org.springframework.boot.test.mock.mockito.MockBean;
19+
import org.springframework.context.annotation.Import;
2420
import org.springframework.data.redis.core.RedisTemplate;
2521
import org.springframework.http.HttpMethod;
2622
import org.springframework.http.MediaType;
2723
import org.springframework.mock.web.MockMultipartFile;
28-
import java.nio.charset.StandardCharsets;
29-
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
3024
import org.springframework.test.context.ActiveProfiles;
3125
import org.springframework.test.web.servlet.MockMvc;
3226
import org.springframework.test.web.servlet.ResultActions;
3327
import org.springframework.transaction.annotation.Transactional;
3428

35-
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
36-
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
37-
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
38-
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
29+
import java.nio.charset.StandardCharsets;
30+
31+
import static org.mockito.ArgumentMatchers.any;
32+
import static org.mockito.BDDMockito.given;
33+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
3934
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
40-
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
35+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
36+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
4137

4238
@SpringBootTest(properties = {
4339
"cloud.aws.credentials.access-key=",
@@ -253,7 +249,7 @@ void t6() throws Exception {
253249
.andDo(print());
254250

255251
// Then (접근 거부 확인)
256-
accessResult.andExpect(status().isForbidden());
252+
accessResult.andExpect(status().isUnauthorized());
257253
}
258254

259255
@Test

src/test/java/com/backend/domain/product/controller/ApiV1ProductControllerTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,25 @@ void getProductsSortedByMemberAndPopularity() throws Exception {
10041004
}
10051005
}
10061006

1007+
@Test
1008+
@DisplayName("특정 회원 상품 목록 조회 - 실패")
1009+
@Transactional
1010+
void getProductsByMemberFailed() throws Exception {
1011+
// when
1012+
long memberId = 9999L;
1013+
ResultActions resultActions = mvc
1014+
.perform(get("/api/v1/products/members/" + memberId))
1015+
.andDo(print());
1016+
1017+
// then
1018+
resultActions
1019+
.andExpect(handler().handlerType(ApiV1ProductController.class))
1020+
.andExpect(handler().methodName("getProductsByMember"))
1021+
.andExpect(status().isNotFound())
1022+
.andExpect(jsonPath("$.resultCode").value("404"))
1023+
.andExpect(jsonPath("$.msg").value("존재하지 않는 회원입니다"));
1024+
}
1025+
10071026
// ======================================= Helper methods ======================================= //
10081027
private ProductCreateRequest createValidRequest() {
10091028
return new ProductCreateRequest(

0 commit comments

Comments
 (0)