본문 바로가기
백엔드 Issue 해결

next (query string) url의 redirect 예외처리

by 코딩균 2021. 12. 2.

이슈 Issue

피키팜 상품 상세 페이지

비로그인 상태에서 <바로 구매하기> 버튼을 누르면 로그인 페이지로 넘어가야 한다

(아쉽게도 비로그인 구매는 2021.12월 기준으로 만들지 않았다.... 회원 구매가 깔끔할 거라 생각...)

 

따라서 <바로 구매하기> 버튼을 누르면 [상품 상세 페이지] 클라이언트는 POST method를 통해 구매할 상품 pk와 상품의 개수 및 옵션을 구매 진행 백엔드로 request를 보낸다

만약 로그인하지 않으면 로그인 페이지로 redirect 된다 

 

Django 기준 @login_required 어노테이션을 사용하였다

login_required annotation

문제는 여기서 생긴다

login_required는 로그인을 인증하는 세션을 가지고 있지 않은 유져가 해당 백엔드 로직에 들어오면 바로 지정된 로그인 페이지로 redirect 시킨다

이떄, next를 key값으로 가진 query string으로 현재 튕겨져나간? 페이지를 value로 가진 아이를 url에 붙여서 보낸다

로그인이 완료되면 다시 로그인 백엔드 로직에서 이전 페이지로 돌아갈 수 있도록 해주기 위해서다

튕긴 페이지 -> 로그인 페이지 -> 로그인 백엔드 로직 -> 튕긴 페이지

문제는 튕긴 페이지가 POST 요청만 받아서 처리하는 백엔드 로직이라는 것이다.

그래서 결과적으로 server error 405가 발생한다

 

해결 Solved

이슈의 원인은 next의 키값 url로 redirect 할 시에 다른 페이지들은 원래 retrieve 시에 GET method로

data를 return해서 문제가 없지만

결제 진행 페이지의 백엔드 로직은 POST 접근을 통해 들어가야 data를 return 받을 수 있기 때문이다

 

원인의 결론은 POST로 받아야 할 백엔드가 GET으로 요청을 받으니 나는 에러였다..! 

비회원이 왔을 때, 로그인 페이지에서 로그인 완료 후 next url로 redirect하는 경우를 고려하지 않았던 것이다..!

 

두가지의 해결 방법을 찾아볼 수 있었다

  • next query를 넘길 때, 구매할 상품 pk, 옵션, 개수도 같이 넘겨서 이전 페이지로 돌아가게 하자
  • 구매진행 백엔드 로직에서 GET요청이 왔을 때, 메인 페이지로 redirect

결국 선택한 방법은 

보안을 위해서 두번째 방법을 선택했다. 

아무래도 결제 관련한 정보 ( 구매 수량, 구매 항목 ) 이 넘어가는 것이라서, 괜히 pk와 구매 수량을 query string 방식으로 url을 통해 만천하에 공개해버릴 순 없다고 생각했다. 

 

why? 보안적 위험?

현재 내가 설계한 시스템에 따르면 구매 진행 백엔드에 로직에서는 해당 pk와 구매수량을 받아서 바로 db에 record를 하나 만든다.

여기서 db 즉 disk에 접근하게 되는데 이때, 저 url을 알고 dos 공격?을 해온다면 수많은 disk io가 일어나서 서버나 db를 과부화시킬 수 있다고 판단했다

( 사실 지식이 아직 얕아 이런 걱정이 사서 하는 걱정은 아닌지 궁금하다....갓 개발자 님들은 댓글을.. ㅎ)

 

그래서 아예 구매진행 백엔드에서 GET method 방식의 접근이 온다면

메인 페이지로 redirect 시켜서 문제를 해결했다. 

405 페이지가 나와서 실제 유져들의 구매의지를 떨어뜨리는 것 보다 메인페이지 한번 더 보고오세요 하는 것이 나아보였다.