일주일 넘게 Test Code 작성과 씨름하고 있다
처음부터 잘 만들어진 교육자료로, 예제 하나하나 따라가면서 학습 했으면 이렇게 오래 걸리지 않았을텐데
처음부터 다 따라 하기에는 프로젝트에 당장 적용해야하니 마음은 급하지
사실 좀 그럴듯한 강의는 죄다 영어로 되어서 중간 중간 띄엄띄엄 속성으로 학습하는 것도 무리였다
(역시 내 깜냥으로 프로젝트에 뛰어드는게 아니었다는 생각이 또 한번 느껴지는 순간이었다)
몇번의 좌절의 순간을 겪다가 오늘 또 2시간 정도의 시간을 잡아먹은 대목이 있었는데 간단히 해결되어서 남겨둔다.
문제는
Controller 테스트 시 mockMvc의 permform 메서드를 통해 Controller 와 요청과 응답을 주고 받는데,
Get 요청에서는 응답을 잘 받아오더니 Put, Patch 요청에 대해서는 403 forbidden을 띄우는 것이었다.
이 것 때문에 Controller의 모든 로직을 get 요청과 동일하게 만들어 보기도 하고,
시큐리티 문제인가 싶어서 Filter를 강제로 꺼보기도 하고(그게 문제엿으면 애초에 get은 되고 put은 안될리가 없긴 하지만...)
별 수를 다 써보다가 이런 저런 키워드를 조합해서 검색해보다가 결국 문제를 파악했다.
원인은
짐작대로 Spring Security에 있었다.
Spring Security는 기본적으로 CSRF(Cross Site Request Forgery) 공격을 방지하는 기능을 가지고 있는데
MockMvc의 요청을 CSRF로 인식한 까닭이었다.
CSRF를 방지하는데에는 여러 기법들이 있는데 ----------------------------------------- 더 공부하면 좋을 내용
Spring Security에서는 CSRF Token을 통한 방지 기법을 활용하고 있다고 한다. ----------- 더 공부하면 좋을 내용
해결법은
위와같이 MockMvcReqeustBuilders 에 with 메서드 안에
SecurityMockMvcRequestPostProcessors.csrf() 를 넣어주는 것이다.
자 그러면 아까와는 다르게 test 가 통과 되면서
MockHttpServeltRequest의 Parameters 부분에 _csrf 값이 추가된 것을 확인할 수 있다.
아마도 저게 CSRF Token 이라는 것으로 추측된다 ㅎㅎ
다음에 공부하면 좋을 내용
1. CSRF를 방지하는데에는 여러 기법들, 사례들
2. Spring Security에서 채택한 CSRF Token 기법