[Django] form 사용시 user input이 url 쿼리에 노출되는 것을 막는 방법 - POST method

느려도 꾸준한 발걸음·2024년 6월 18일
0

Django Web dev

목록 보기
6/12

오늘은 form을 Django 속에서 사용할 때의 주의사항을 알아보겠습니다.
이해를 위해 예제는 제가 상상할 수 있는 가장 쉬운 예시로 하겠습니다.

사용자에게 두 수를 입력받고,
결과를 띄워보도록 합시다.

{% extends "base.html" %} 

{% block content %}
<h1>welcome, {{name}}</h1>

<form action="add" method="post">
  
  {% csrf_token %} 
  
  첫 번째 숫자를 입력하세요 <input type="text" name="num1" /><br />
  두 번째 숫자를 입력하세요 <input type="text" name="num2" /><br />

  <button type="submit">제출하기</button>

</form>
{% endblock %}

다음과 같이 home.html 파일 안에 form 태그를 생성했습니다.

action속성에 add를 넣었으니, 유저가 form을 제출하면, 유저가 입력한 데이터는 url의 /add 경로로 전달되겠네요.

method는 따로 정해주지 않았으니 디폴트로 GET이겠네요. (뒤에서 POST로 바꿀 예정입니다만, GET의 문제점을 알아보고자 우선 method를 GET으로 유지하겠습니다.)

자, 그럼 calc app의 urls.py에 add경로에 대한 라우팅도 해줘야겠네요.

짠! 보이시나요?
라인 7번에 add경로에 대한 라우팅을 잘 해주었습니다.
두 번째 인자의 처리함수 adder는 calc app내의 views.py에 생성해주었습니다.

adder함수를 통해 사용자가 입력한 두 값을 더합니다.
최종 계산된 값을 화면에 띄워줘야겠죠?

연습을 위해 저희는 굳이굳이 새로운 화면으로 전환하여 결과만을 띄워주도록 해봅시다.

지난 차시처럼 render의 속성들을 잘 활용하겠습니다.
adding_result.html이라는 별도의 파일을 생성하고,
views.py의 adder함수에서 계산해서 구한 값을 일종의 React prop처럼 전달해줍시다. (지난 시간에 배운 DTL입니다)


이렇게, DTL을 이용해 결과를 띄워줍니다!

여기서, 1번 라인을 주목해주세요.
앞으로 저희가 개발할 때에는, 모든 페이지에 공통으로 적용될 레이아웃을 base.html으로 만들어두고, 이걸 계속 불러와 페이지별로 달라지는 내용만 작성할 것입니다.

웹 개발 경험이 있으신 분들이라면, 컴포넌트의 개념을 생각해주시면 좋을 것 같습니다.

장고 템플릿에서는 {% %} 속에 파이썬 문법을 사용할 수 있습니다.
extends를 사용하여 기본 페이지를 상속받고,
block conent와 endblock 사이에 페이지를 개발해주시면 됩니다.


base 파일은 이렇게 생겼습니다.
장고에서는 상속받은 페이지 내용 외에 추가할 내용을
{% block content %} 와 {% endblock %} 사이에 페이지 내용을 작성해주시면 됩니다.

자 그럼, 지금까지 만든 내용을 살펴보고, 무엇이 문제인지 확인해볼까요?

이렇게 숫자를 입력하고 제출을 누르면...
결과는 잘 나오지만, url의 쿼리 부분에 유저가 입력한 값이 전부 노출이 되네요.

만약 해당 form이 유저의 아이디와 비밀번호를 입력받고 있었다면?
생각만해도 아찔하죠.

유저가 폼에 입력한 정보를 url에서 가리기 위해서, 저희는 http method를 POST로 바꿔줘야 합니다.

이를 위해 가장 먼저, home.html파일의 form태그에 method를 post로 바꿔주겠습니다. form태그는 개발자가 method를 지정해주지 않으면 기본적으로 GET이 되죠. (html 기본 문법이 약하신 분들은 html을 반드시 학습해주세요)


다음과 같이 method="post"를 form태그에 추가해줬습니다!
추가로, form 태그를 사용할 땐, 장고에서 제공하는 csrf_token을 사용해야 합니다.

이를 사용해 http 통신시 CSRF공격으로부터 우리 사이트를 보호할 수 있답니다!

html의 내용을 수정했으니, 이 값을 받아오는 views.py도 내용을 수정해야겠네요!


라인 8,9에서 GET을 POST로 바꿔주면 됩니다.
POST request중 num1, num2라는 name을 가진 요소의 유저 입력 값을 받아오겠다!~ 이런 의미로 이해해주세요.

자.. 이제 url에 우리의 민감한 정보가 잘 숨겨졌는지 볼까요?

아주 잘 가려졌네요!

앞으로 폼태그는 post와 함께 사용해요!

결론

form태그 사용시엔, 아래의 두 가지 사항을 주의합니다.

  • form 의 method는 post로 지정해 url쿼리에 유저input이 노출되는 것을 방지
  • form 태그 안에 {% csrf_token %} 사용해 csrf공격 방어

아무쪼록, 다음 시간에 뵙겠습니다.
감사합니다

참고한 영상 https://www.youtube.com/watch?v=OTmQOjsl0eg

profile
웹 풀스택 개발자를 준비하고 있습니다. MERN스택을 수상하리만큼 사랑합니다.

0개의 댓글