From ec24e5be1d01ac4f7830236d103fd688410cd63b Mon Sep 17 00:00:00 2001 From: yongckim Date: Thu, 29 Feb 2024 18:48:07 +0900 Subject: [PATCH] =?UTF-8?q?:white=5Fcheck=5Fmark:=20[STMT-146]=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=95=84=EC=9B=83=20API=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/index.adoc | 15 ++++ .../common/auth/config/SecurityConfig.java | 3 +- .../common/auth/filter/LogoutFilterTest.java | 77 +++++++++++++++++++ .../com/stumeet/server/stub/TokenStub.java | 2 +- .../com/stumeet/server/template/ApiTest.java | 1 - src/test/resources/application.yml | 2 +- 6 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/stumeet/server/common/auth/filter/LogoutFilterTest.java diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index e1cd8ac5..c2a5685c 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -35,6 +35,21 @@ include::{snippets}/social_login/fail/not-exist-header/response-body.adoc[] include::{snippets}/social_login/fail/invalid-token/response-fields.adoc[] +== 로그아웃 + +로그아웃 시 사용되는 API입니다. + +=== POST /api/v1/logout + +==== 요청 + +include::{snippets}/logout/success/http-request.adoc[] +include::{snippets}/logout/success/request-headers.adoc[] + +==== 응답 성공 (200) +include::{snippets}/logout/success/response-body.adoc[] +include::{snippets}/logout/success/response-fields.adoc[] + == 토큰 재발급 서버로 부터 받은 액세스 토큰이 만료된 경우 액세스 토큰 재발급을 위해 사용되는 API입니다. diff --git a/src/main/java/com/stumeet/server/common/auth/config/SecurityConfig.java b/src/main/java/com/stumeet/server/common/auth/config/SecurityConfig.java index e04322b9..0eb66a6f 100644 --- a/src/main/java/com/stumeet/server/common/auth/config/SecurityConfig.java +++ b/src/main/java/com/stumeet/server/common/auth/config/SecurityConfig.java @@ -66,7 +66,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth -> { auth.requestMatchers(HttpMethod.POST, "/api/v1/oauth").permitAll(); - auth.requestMatchers(HttpMethod.POST,"/api/v1/tokens").permitAll(); + auth.requestMatchers(HttpMethod.POST, "/api/v1/tokens").permitAll(); auth.requestMatchers("/h2-console/**").permitAll(); auth.requestMatchers("/docs/**").permitAll(); auth.requestMatchers("/api/v1/signup").hasAnyAuthority("FIRST_LOGIN"); @@ -82,6 +82,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http.build(); } + @Bean public SecurityContextRepository securityContextRepository() { return new RequestAttributeSecurityContextRepository(); diff --git a/src/test/java/com/stumeet/server/common/auth/filter/LogoutFilterTest.java b/src/test/java/com/stumeet/server/common/auth/filter/LogoutFilterTest.java new file mode 100644 index 00000000..4decd1dd --- /dev/null +++ b/src/test/java/com/stumeet/server/common/auth/filter/LogoutFilterTest.java @@ -0,0 +1,77 @@ +package com.stumeet.server.common.auth.filter; + +import com.stumeet.server.common.auth.model.AuthenticationHeader; +import com.stumeet.server.common.token.JwtTokenProvider; +import com.stumeet.server.common.util.JwtUtil; +import com.stumeet.server.member.adapter.out.persistence.JpaMemberRepository; +import com.stumeet.server.member.adapter.out.persistence.MemberJpaEntity; +import com.stumeet.server.stub.MemberStub; +import com.stumeet.server.stub.TokenStub; +import com.stumeet.server.template.ApiTest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.transaction.annotation.Transactional; + +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@Transactional +public class LogoutFilterTest extends ApiTest { + + @Autowired + private JpaMemberRepository jpaMemberRepository; + + @Autowired + private JwtTokenProvider jwtTokenProvider; + + @Autowired + private RedisTemplate redisTemplate; + + @Nested + @DisplayName("로그아웃") + class Logout { + + private final String path = "/api/v1/logout"; + + @BeforeEach + void setUp() { + MemberJpaEntity entity = jpaMemberRepository.save(MemberStub.getMemberEntity()); + redisTemplate.opsForValue() + .set( + JwtUtil.resolveToken(TokenStub.getMockAccessToken()), + jwtTokenProvider.generateRefreshToken(entity.getId()) + ); + } + + @Test + @DisplayName("[성공] 로그아웃에 성공합니다.") + void successTest() throws Exception { + mockMvc.perform(post(path) + .header(AuthenticationHeader.ACCESS_TOKEN.getName(), TokenStub.getMockAccessToken())) + .andExpect(status().isOk()) + .andDo(document("logout/success", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(AuthenticationHeader.ACCESS_TOKEN.getName()).description("서버로부터 전달받은 액세스 토큰") + ), + responseFields( + fieldWithPath("code").type(JsonFieldType.NUMBER).description("응답에 대한 결과 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("응답에 대한 메시지") + ) + ) + ); + } + } +} diff --git a/src/test/java/com/stumeet/server/stub/TokenStub.java b/src/test/java/com/stumeet/server/stub/TokenStub.java index d0ee53ca..48b8fac0 100644 --- a/src/test/java/com/stumeet/server/stub/TokenStub.java +++ b/src/test/java/com/stumeet/server/stub/TokenStub.java @@ -17,7 +17,7 @@ public static String getExpiredAccessToken() { } public static String getInvalidToken() { - return "invalidToken"; + return "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJTVFVNRUVUIiwic3ViIjoiMSIsImF1dGgiOiJGSVJTVF9MT0dJTiIsImV4cCI6MTcwOTA0MTM1Mn0.1dU2fb1wUgJeV8R1RAjFpKx3g3qToRZnft1lxSejL7o"; } public static String getMockAccessToken() { return "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJTVFVNRUVUIiwic3ViIjoiMSIsImF1dGgiOiJGSVJTVF9MT0dJTiIsImV4cCI6MTcwOTA0MTM1Mn0.1dU2fb1wUgJeV8R1RAjFpKxBg3qToRZnft1lxSejL7o"; diff --git a/src/test/java/com/stumeet/server/template/ApiTest.java b/src/test/java/com/stumeet/server/template/ApiTest.java index e1346146..6185174d 100644 --- a/src/test/java/com/stumeet/server/template/ApiTest.java +++ b/src/test/java/com/stumeet/server/template/ApiTest.java @@ -41,7 +41,6 @@ public abstract class ApiTest { @BeforeEach void setUpMockMvc(WebApplicationContext context, RestDocumentationContextProvider provider) { - this.mockMvc = MockMvcBuilders.webAppContextSetup(context) .addFilter(new CharacterEncodingFilter("UTF-8", true)) .apply(documentationConfiguration(provider)) diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 911b1220..5774e71f 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -39,4 +39,4 @@ oauth: apple: url: http://localhost:8089 kakao: - url: http://localhost:8089 + url: http://localhost:8089 \ No newline at end of file