반응형

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.

 

오늘은 잔망과 루피의 이름으로 다른 코드 스타일을 용서하지 않을 예정입니다.

 

여러명이서 진행한 프로젝트인만큼 파일마다 개성이 뚜렷했는데, 찾아다니면서 맞추기에는 효율도 떨어지고 놓치는 부분도 분명이 있을 것이라 생각했습니다.

 

또 다른 문제는 제가 가진 코드 컨벤션 같은 것이 없기에 다른 이가 만들어 놓은 포맷팅을 우선 일괄적으로 적용하는 것이 필요하겠다는 판단을 했습니다.

 

그래서 이번 목표는 다른 이의 코드 스타일을 일괄로 한 번에 적용하자! 입니다🤓!

 

1. xml 형식의 스타일 가이드를 하나 구해봅니다.

* intelliJ java 기준입니다.

https://github.com/google/styleguide/blob/gh-pages/intellij-java-google-style.xml

 

styleguide/intellij-java-google-style.xml at gh-pages · google/styleguide

Style guides for Google-originated open-source projects - google/styleguide

github.com

https://github.com/woowacourse/woowacourse-docs/blob/main/styleguide/java/intellij-java-wooteco-style.xml

 

woowacourse-docs/styleguide/java/intellij-java-wooteco-style.xml at main · woowacourse/woowacourse-docs

우아한테크코스 문서를 관리하는 저장소. Contribute to woowacourse/woowacourse-docs development by creating an account on GitHub.

github.com

 

 

2. IntelliJ에 적용

* Window 기준입니다.

File - Settings - Editor - Code Style - Java

Scheme - 톱니바퀴 - Import Scheme - IntelliJ IDEA code style XML - Apply

 

 

3. 코드 저장 시마다 Formmatting 적용 설정

File - Settings - Tools - Actions on Save

* Reformat code: 저장 시마다 formmating 적용

* Optimize imports: 사용하지 않는 import문 제거

🚨 Rearrange code, Run code cleanup: 코드 위치 변경, 불필요한 코드 제거 등의 기능을 제공하지만 사이드 이펙트 우려가 있어 사용하지 않습니다.

 

 

4. 전체 파일에 적용

* 개인이 따로 줄 바꾸기 한 게 사라질 수 있으므로 Line Break에 대한 경고창을 확인해야 합니다.

* 개별 파일에서 적용: ctrl + alt + L

* 특정 폴더 내의 모든 파일 적용: Project 창에서 해당 폴더를 클릭한 후 ctrl + alt + L

  🚨 Default로 Clean Up Code가 Check되어있으므로 유의

 

 

+ 2024.10.03

Code Style을 자동으로 적용하도록 했는데, xml에서 길이가 길어지니 자동 줄바꿈을 해서 저장하는 문제가 있었습니다.

IntelliJ 기준 Settings - Editor - Code Style - Formatter 탭

Do not Formatter에 특정 파일을 추가할 수 있습니다.

 

🙋‍♀️

본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.

 

📑

참고 자료

https://yeon-kr.tistory.com/197

 

[Intellij] Google Java auto-formatting 적용

1) 서론 여러 사람이 함께 코드를 작성할 때는 다양한 스타일의 코드가 작성됩니다. 같은 목적의 코드라도, 개개인의 스타일은 다를 수밖에 없는데요. 만약 큰 회사 혹은 조직이라면 통일된 코드

yeon-kr.tistory.com

https://velog.io/@pgmjun/IntelliJ-%EC%BD%94%EB%93%9C-%EC%8A%A4%ED%83%80%EC%9D%BC%EC%9D%84-%EC%84%A4%EC%A0%95%ED%95%B4%EB%B3%B4%EC%9E%90-feat.%EC%9A%B0%ED%85%8C%EC%BD%94

 

[IntelliJ] 코드 스타일을 설정해보자 (feat.우테코)

오늘부터 시작한 우아한 테크코스 6기의 프리코스를 수행하면서기능 구현에 집중하느라 코드 포맷을 정리하지 못해, 기능 구현 이후 Commit 직전일일히 객체를 찾아다니며 Command + Option + L (코드

velog.io

 

반응형
반응형

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.

 

 

 

사실 그간 흐린눈을 하고 있던 작업이 몇 개 있었습니다.

 

그 중에 하나가 .gitignore를 업데이트 하는 것이었습니다.

 

기존에 .idea 파일이 올라가 있고, 그 외 환경 설정 관련 파일들도 올라가있던 것이 있어써 이번에 파일도 업데이트하고, 기존에 Github에 올라가버린 파일들은 어찌하나에 대해서 간단히 정리해보고자 합니다.

 

.gitignore에 적힌 파일들,, git push origin developer를 적더라도,, 그냥 지나가면 돼요,,⭐

 

 

 

1. .gitignore 파일 자동으로 생성하기

https://www.toptal.com/developers/gitignore/

 

gitignore.io

Create useful .gitignore files for your project

www.toptal.com

저 같은 경우에는 아래와 같이 선택하였습니다.

 

운영체제: Window

개발 환경(IDE): IntelliJ, Visual Studio Code (← Front가 React여서 추가했습니다.)

프로그래밍 언어: Java, React(← JavaScript는 없어서 React를 바로 추가했습니다.)

빌드 도구: Gradle

 

 

2. Github에 올리고 싶지 않은 파일 or 폴더 추가

  • 보안상으로 위험성이 있는 파일
  • 프로젝트와 관계없는 파일
  • 용량이 너무 커서 제외해야되는 파일

저는 API Key가 들어있는 application.properties 파일을 추가해주었습니다.

 

 

3. .gitignore 재 적용

git rm -r --cached . 
git status
git add .
git commit -m "#-- update .gitignore"
git push origin developer

일반적인 push 과정에서 cached가 추가되었습니다.

Git 저장소에서 트래킹 중인 모든 파일을 스테이지에서 제거하지만, 실제 파일은 삭제하지 않는 명령어입니다.

.gitignore에 추가한 파일들이 GitHub에서 제거된 이유는 Git에서 파일을 추적하지 않게 만든 후 커밋을 했기 때문입니다.

⭐ git status를 통해서 git 명령어가 제대로 동작하는지 확인해줍니다.

 

 

4. push 후, Github에서 삭제되지 않는 파일 확인하기

저 같은 경우에는 .ignore에 추가한 .idea 폴더 및 하위 파일이 삭제되지 않았습니다.

add까지는 동작하는데, commit을 하려고하면 commit할 게 없다고 하는데, 제가 분명 봤거든요. add까지 되는걸 말이죠.

 

개인적인 생각으로는

파일 트래킹에서 제거 → 해당 내역 staging → 트래킹하지 않기로 했으므로 원격으로 Commit할 게 없음

의 무한 굴레에 빠진 것 같아 Github에서 폴더를 바로 삭제하였습니다.

누르면 안될 것 같은 Delete directory를 누르면 됩니다.

 

저는 현재 main + developer를 사용하는데, main에서 folder를 삭제했으므로, 혹시 몰라 developer 작업 전 git pull origin main을 한 번 입력했습니다.

 

 

+ .idea를 .gitignore에 추가하는 이유

.idea 폴더는 IntelliJ 의 IDE 옵션(프로젝트별 설정값)을 저장하는 폴더로, IDE 의 각 옵션은 작업자의 컴퓨터 환경에 맞춰서 변경됩니다.

개인 옵션이 설정되어 있는 상태에서 다른 작업자에게 공유하면 오류가 발생할 수 있어 주의 해야 합니다.

따라서 다른 작업자가 소스를 받을때 영향을 주지않기 위해 .gitignore에 .idea를 추가 합니다.

 

 

 

🙋‍♀️

본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.

 

📑

참고 자료

https://velog.io/@hxeyexn/Git-.gitignore-%EB%8B%A4%EC%8B%9C-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

 

[Git] .gitignore 다시 적용하기

프로젝트 초기 생성 때 gitignore를 생성하지 않았거나, 프로젝트 중간에 gitignore 파일을 수정해야할 경우가 종종 생긴다.이때 gitignore 파일 수정만으로는 ignore가 적용되지 않는다.따라서 기존 cache

velog.io

https://otrodevym.tistory.com/entry/GIT-Intellij%EC%97%90%EC%84%9C-gitignore%EA%B0%80-%EB%90%98%EC%A7%80-%EC%95%8A%EC%9D%84-%EA%B2%BD%EC%9A%B0-%EC%A1%B0%EC%B9%98-%EB%B0%A9%EB%B2%95

 

[git] Intellij에서 gitignore가 되지 않을 경우 조치 방법

상황 인텔리제이에서 .class를 제외하고 싶은데 제외가 되지 않았습니다. 문제 파악 .class와 같은 추가 되지 않아야 하는데 제외되지 않는 경우가 있습니다. 이 경우에는 이미 add되어 있기 때문에

otrodevym.tistory.com

https://velog.io/@bybye527/Git-.gitignore-%EC%9D%B4%EB%9E%80-feat.idea

 

[Git] .gitignore 이란? (feat.idea)

보안상으로 위험성이 있는 파일프로젝트와 관계없는 파일용량이 너무 커서 제외해야되는 파일편리성 제공자동생성 사이트 Gitignore.io검색창에 운영체제, 개발환경(IDE), 프로그래밍 언어를 검색

velog.io

 

반응형
반응형

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.

 

 

최근 제 Controller 테스트 코드가 열린교회 닫힘이었습니다.

 

분명 전 create API에 대해서 permitAll()을 설정했는데, 테스트 코드로 가입이라도 하려면 칼같이 403 Forbidden을 반환했습니다.

아니, 제가 괜찮다는데.. Postman에서도 괜찮다고 했는데 테스트 코드가 거절을 했습니다.

 

가입을 못하면,, 좀 이상하기에,, 왜 문제가 발생하는지, 어떻게 수정했는지 정리해보고자 합니다.

 

Test Code에서 403 Forbidden이 발생하는 원인1
CSRF(Cross-Site Request Forgery)

  * @AutoConfidurationMockMvc

    * MockMvc 테스트 환경에서 CSRF 보호가 기본적으로 적용  

  * CSRF(Cross-Site Request Forgery) 보호 때문에 POST 요청에 대해 CSRF 토큰이 필요

cf. csrf 공격

  * 인증된 사용자가 웹 애플리케이션에 특정 요청을 보내도록 유도하는 공격 행위

  * 원하는 요청을 위조한 후, 이메일이나 웹사이트에 요청이 삽입된 하이퍼링크를 심어 놓아 사용자가 해당 링크를 클릭하면 요청이 자동으로 전송

CSRF(Cross-Site Request Forgery) 관련 해결방안

1. SecurityFilterChain에서 비활성화 처리

  * csrf(AbstractHttpConfigurer::disable) 

2. Test 코드에서 csrf 활성화 처리

  * with(csrf())

 

⭐ JWT는 Token 방식으로, crfs 보호 방식을 사용하지 않아도 괜찮음

  * CSRF 토큰을 사용하여 클라이언트가 서버에 요청할 때마다 유효한 토큰을 함께 전송해야만 요청이 성공하도록 하는 방식으로 보안을 강화 -> CSRF 토큰 대신 JWT 사용

 

 

Test Code에서 403 Forbidden이 발생하는 원인2
Spring Security Filter

* @AutoConfidurationMockMvc

  * SecurityFilterChain 설정 시, API 관련 권한 부족

 

Spring Security Filter 관련 해결방안

1. @AutoConfidurationMockMvc(addFilters = false)

  * Spring Security Filter 해제

🚨인증없는 테스트는 앙꼬없는 찐빵으로 특별한 이유가 없으면 사용 X

2. SecurityFilterChain에서 해당 uri 설정 확인

  * permitAll() 처리가 되어있는지 확인

  * anyRequest().authenticated() 처리가 되어있을 경우, 잘못된 API 주소로 요청 시, 401 오류 발생(= 인증이 문제가 됨)

  * anyRequest().authenticated() 처리가 안되어있을 경우, 잘못된 API 주소로 요청 시, 403 오류 발생(= 차단 됨)

 

저는 회원가입 API 주소를 최근에 REST API에 맞춰 create -> new로 변경하였는데, SecurityFilterChain 수정이 안되어있던 게 문제가 되었습니다. 문자열 처리가 되어있는 부분은 늘 유의를 해야합니다😮!

 

 

SecurityConfig.java
@Configuration // 스프링의 환경설정 파일임을 의미하는 애너테이션
@EnableWebSecurity // 모든 요청 URL이 스프링 시큐리티의 제어를 받도록 만드는 애너테이션
@RequiredArgsConstructor
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.httpBasic(AbstractHttpConfigurer::disable) // 기본 HTTP 인증을 비활성화
                .csrf(AbstractHttpConfigurer::disable) // CSRF 보호를 비활성화, CSRF 토큰을 사용하여 클라이언트가 서버에 요청할 때마다 유효한 토큰을 함께 전송해야만 요청이 성공하도록 하는 방식으로 보안을 강화 -> 토큰으로 대체
                .cors(httpSecurityCorsConfigurer -> corsConfigurationSource())
                .sessionManagement(sessionManagement ->
                        sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 세션을 사용하지 않고, 상태를 저장하지 않도록 설정(STATLESS)
                ).authorizeHttpRequests(auth -> auth
                        .requestMatchers("/api/v2/users/login").permitAll()
                        .requestMatchers("/api/v2/users/new").permitAll()
                        .requestMatchers("/api/v2/users/me", "/api/v2/users/logout").hasRole("USER")
                        .requestMatchers("/api/v2/users/reissue").permitAll()
                        .anyRequest().authenticated() // 이 외의 접근은 인증이 필요
                )
                .addFilterBefore(jwtAuthenticationFilterForSpecificUrls(), UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
}

 

UserControllerTest.java
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {
    @Test
    @DisplayName("Controller: 회원 가입 실패, 중복된 이메일")
    void createFailDuplicateEmail() throws Exception {
        // given
        SignUpRequestDTO signUpDto = SignUpRequestDTO.builder()
                .status("M")
                .email("temp@email.com")
                .phone("01023698745")
                .nickname("name")
                .password("temp123!")
                .confirmPassword("temp123!")
                .build();

        // when // then
        doThrow(new BusinessException(ErrorCode.DUPLICATED_EMAIL))
                .when(userService).create(any(SignUpRequestDTO.class));

        mockMvc.perform(post("/api/v2/users/new")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(signUpDto)))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.errorMessage").value("이미 존재하는 이메일 입니다."));

        // 회원 생성 메소드가 호출되었는지 확인
        verify(userService).create(refEq(signUpDto));
    }
}

 

 

 

🙋‍♀️

본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.

 

📑

참고 자료

https://lemontia.tistory.com/1088

 

springboot Test 중에 403, 401 에러가 날때(spring security)

Spring Security 가 구성되어 있는 프로젝트에서 Controller 테스트를 하다보면 인증때문에 에러가 난다. WebMvcTest로 수행했다 하더라도 Security 는 Filter 영역에 추가되는 것이기 때문에 그렇다. WebMvcTest

lemontia.tistory.com

https://nordvpn.com/ko/blog/csrf/?srsltid=AfmBOoqLrbNTfgqsgkW6o-bHv3MfBZW8uVXqHFa3HgW2ueu6LQpSqQD5

 

크로스 사이트 요청 위조(CSRF)의 의미 | NordVPN

크로스 사이트 요청 위조란 무엇일까요? 이 글에서 크로스 사이트 요청 위조의 의미와 방지 방법을 확인해 보세요

nordvpn.com

https://velog.io/@sysy123/Spring-Boot-Error-ControllerTest-Spring-Security-403-%EC%97%90%EB%9F%AC

 

[Spring Boot] Error: ControllerTest + Spring Security 403 에러

1. ControllerTest에 @AutoConfigureMockMvc(addFilters = false) 추가 2. SecurityConfig에 http.csrf().disable() 추가 3. Test 코드에 @WithMockUser, with(csrf()) 추가

velog.io

 

반응형
반응형

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.

 

사실 테스트 코드 작성 관련해서는 이전에 한 번 글을 쓴 적이 있습니다.

 

그 때는 Service 코드를 검증하였습니다.

Spring 강의를 들을 때, 테스트 코드를 Service 단에서 작성했기에 해당 코드를 응용해가며 리팩토링할 때 테스트 코드를 만들어갈 수 있었습니다.

 

하지만, Controller는 테스트 코드를 작성해본 적이 없습니다..?

 

그래서 PostMan을 사용하다가, Postman에서 검증이 다 끝났기에 Test Code를 공부하면서 작성해보면 좋을 것 같아 글을 작성하게 되었습니다.

 

Contoller 테스트 코드를 작성하며 쓰는, PostMan과 헤어질 결심..!

 

https://hj0216.tistory.com/933

 

[1년 후 마실가실] Test Code 작성

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다. Test Code가 없던 1년 전 마실가실, 리팩토링을 하면서 Test Code가 생겼습니다.예상 동작과 실제 동작을 비교하여 빠르

hj0216.tistory.com

 

UserControllerTest.java
@SpringBootTest
@AutoConfigureMockMvc(addFilters = false)
class UserControllerTest {
    @Autowired MockMvc mockMvc;
    @Autowired ObjectMapper objectMapper;
    @MockBean UserService userService;

    @Test
    @DisplayName("Controller: 회원 가입 성공")
    void createSuccess() throws Exception {
        // given
        SignUpRequestDTO signUpDto = SignUpRequestDTO.builder()
                .status("M")
                .email("new@email.com")
                .phone("01023698741")
                .nickname("name")
                .password("newnew123!")
                .confirmPassword("newnew123!")
                .build();

        // when // then
        mockMvc.perform(post("/api/v2/users/new")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(signUpDto)))
                .andExpect(status().isCreated());

        // 회원 생성 메소드가 호출되었는지 확인
        verify(userService).create(refEq(signUpDto));
    }

    @Test
    @DisplayName("Controller: 회원 가입 실패, 중복된 이메일")
    void createFailDuplicateEmail() throws Exception {
        // given
        SignUpRequestDTO signUpDto = SignUpRequestDTO.builder()
                .status("M")
                .email("temp@email.com")
                .phone("01023698745")
                .nickname("name")
                .password("temp123!")
                .confirmPassword("temp123!")
                .build();

        // when // then
        doThrow(new BusinessException(ErrorCode.DUPLICATED_EMAIL))
                .when(userService).create(any(SignUpRequestDTO.class));

        mockMvc.perform(post("/api/v2/users/new")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(signUpDto)))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.errorMessage").value("이미 존재하는 이메일 입니다."));

        // 회원 생성 메소드가 호출되었는지 확인
        verify(userService).create(refEq(signUpDto));
    }
}

@AutoConfigureMockMvc(addFilters = false)

  * MockMvc 객체(HTTP 요청과 응답을 모킹(mocking)하여 컨트롤러의 동작을 테스트할 수 있는 객체)를 자동으로 설정

  * addFilters = false: Spring Security와 같은 필터를 적용하지 않도록 설정

 

MockMvc

  * HTTP 요청과 응답을 모킹(mocking, 실제 서버에 HTTP 요청을 보내지 않고, 테스트 환경에서 HTTP 요청을 모방하여 응답을 받을 수 있도록 하는 것)하여 컨트롤러의 동작을 테스트할 수 있는 객체

  * 실제 서버를 띄우지 않고도 컨트롤러와 상호작용할 수 있음

 

ObjectMapper

  * Java 객체를 JSON으로 직렬화하거나, 반대로 JSON을 Java 객체로 역직렬화

    * objectMapper.writeValueAsString: 객체를 JSON으로 직렬화 -> request body에 저장

 

@MockBean

  * 테스트 시, UserService 클래스의 가짜(Mock) 객체를 생성

  * UserService 사용 시, 실제로 데이터베이스에 접근하거나 복잡한 로직을 처리하지 않고, 테스트에서 설정한 동작만을 수행

    * doThrow(): 예외가 발생하도록 모킹

    * doNothing(): 메소드를 호출 시, 아무런 동작도 하지 않도록 모킹

  * 특정 메소드가 호출되었는지, 또는 어떤 인자를 전달받았는지 확인할 수 있음

 

mockMvc.perform()

  * MockMvc를 사용해 GET/POST/PUT/PATCH/DELETE 요청

 

verify()

  * 메소드가 호출 확인

  * refEq(): 값 비교

 

 

 

🙋‍♀️

본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.

 

📑

참고 자료

https://sbs1621.tistory.com/54

 

[Spring] MockMvc를 이용한 Controller의 Test Code(JUnit5) 작성하기

간단하게 작성할 수 있는 게시판 Controller에 대한 테스트코드입니다. 테스트코드 추가하기 컨트롤러에서 cmd + shift + t(윈도우는 control + shift + t)를 누르시면 간단하게 테스트코드를 만들 수 있습

sbs1621.tistory.com

 

반응형
반응형

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.

 

사소한 생각으로부터 시작된 Filter Chain 수정 이야기..

 

필터로 Validate를 하니, 모든 url에 대해 Filter가 적용이 되어 너무 비효율적이지 않은가에 대한 해답을 들고 왔습니다.

 

JwtAuthentificationFilter와 함께할 합격의 목걸이를 받을 url 설정 기록 입니다..

 

 

 

관련된 글

https://hj0216.tistory.com/947

 

[1년 후 마실가실] JWT와 로그아웃(3) 로그아웃

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.  스마트 루피를 데려온 이유는 스마트하게 로그아웃을 완성했기 때문입니다. JWT와 로그아웃(1) 게시물을 8월 23일

hj0216.tistory.com

 

 

JwtAuthentificationFilter.java
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.httpBasic(AbstractHttpConfigurer::disable)
            .csrf(AbstractHttpConfigurer::disable)
            .cors(httpSecurityCorsConfigurer -> corsConfigurationSource())
            .sessionManagement(sessionManagement ->
                    sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            )                .authorizeRequests((auth) -> auth
                            .requestMatchers("/api/v2/users/login").permitAll()
                            .requestMatchers("/api/v2/users/me", "/api/v2/users/logout").hasRole("USER")
            )
            .addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class);

    return http.build();
}

🚨문제: JwtAuthentificationFilter에서 Access Token의 유효성 검증을 수행하는데, 유효성 검증이 필요없는 회원가입이나 Access Token 재발행에서도 Filter가 동작

 

🤓 해결 방안: 특정 url에서만 filter가 동작하도록 수정

 

🛠️해결1

shouldNotFilter
public JwtAuthenticationFilter jwtAuthenticationFilterForSpecificUrls() {
    return new JwtAuthenticationFilter(jwtTokenProvider) {
        @Override
        protected boolean shouldNotFilter(HttpServletRequest request) {
            String path = request.getServletPath();
            return !("/api/v2/users/login".equals(path) || "/api/v2/users/me".equals(path) || "/api/v2/users/logout".equals(path));
        }
    };
}

public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.httpBasic(AbstractHttpConfigurer::disable) // 기본 HTTP 인증을 비활성화
            .csrf(AbstractHttpConfigurer::disable) // CSRF 보호를 비활성화, CSRF 토큰을 사용하여, 클라이언트가 서버에 요청할 때마다 유효한 토큰을 함께 전송해야만 요청이 성공하도록 하는 방식으로 보안을 강화 -> 토큰으로 대체
            .cors(httpSecurityCorsConfigurer -> corsConfigurationSource())
            .sessionManagement(sessionManagement ->
                    sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 세션을 사용하지 않고, 상태를 저장하지 않도록 설정(STATLESS)
            ).authorizeHttpRequests(auth -> auth
                    .requestMatchers("/api/v2/users/login").permitAll()
                    .requestMatchers("/api/v2/users/me", "/api/v2/users/logout").hasRole("USER")
            )
            .addFilterBefore(jwtAuthenticationFilterForSpecificUrls(), UsernamePasswordAuthenticationFilter.class);

    return http.build();
}

 

🛠️해결2

WebSecurityCustomizer
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
    return (web) -> web.ignoring()
            .requestMatchers("/api/v2/users/new", "/api/v2/users/reissue");
}

 

⭐ 차이점

* shouldNotFilter : 특정 경로에 대한 특정 필터만 제외

* WebSecurityCustomizer: 경로에 대해 모든 필터 체인을 비활성화

 

 

 

🙋‍♀️

본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.

 

📑

참고 자료

 

반응형