Codong's Development Diary RSS ํƒœ๊ทธ ๊ด€๋ฆฌ ๊ธ€์“ฐ๊ธฐ ๋ฐฉ๋ช…๋ก
2021-03-20 21:54:25

๐Ÿ˜„ ๊ฐœ์š”


๊ฐ„๋งŒ์— ์žฅ๊ณ ๋กœ ๋‹ค์‹œ ๊ฐœ์ธ์ ์ธ toy project๋ฅผ ํ•ด๋ณด๊ณ  ์‹ถ์–ด์„œ, ์žฅ๊ณ  ํ”„๋กœ์ ํŠธ ์ƒ์„ฑํ•˜๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ POST ์š”์ฒญ ๋น„๋™๊ธฐํ†ต์‹ ์„ ์ด์šฉํ•ด๋ณด๊ณ  ์‹ถ์–ด์„œ jquery์˜ ajax๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. ์—ญ์‹œ, ERROR๊ฐ€ ์•ˆ๋œฐ๋ฆฌ ์—†๋‹ค.


๐Ÿ˜ฑ ๋ฌธ์ œ์ 


์šฐ์„  ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ์•„์ฃผ ๊ฐ„๋‹จํ–ˆ๋‹ค.

$.ajax({
      type:'POST',
      url:'/search',
      data:JSON.stringify(geodata),
      success:function(json){
          console.log("to view data pass success",json);

      },
      error : function(xhr,errmsg,err) {
      console.log(xhr.status + ": " + xhr.responseText); 
      }
      });

search ๋กœ POST ์š”์ฒญ์„ ๋ณด๋ƒˆ๋Š”๋ฐ.......?

Forbidden (CSRF cookie not set.): /search
[20/Mar/2021 10:47:16] "POST /search HTTP/1.1" 403 2864

๊ฒฐ๊ณผ๋Š” ์ฒ˜์ฐธํ–ˆ๋‹ค....โ˜ ๏ธโ˜ ๏ธโ˜ ๏ธโ˜ ๏ธโ˜ ๏ธ

๊ฐ„๋‹จํ•˜๊ฒŒ ์š”์•ฝํ•˜์ž๋ฉด django์˜ CSRF(Cross Site Request Forgery ์‚ฌ์ดํŠธ ๊ฐ„ ์š”์ฒญ ์œ„์กฐ) ๋ณด์•ˆ ์ •์ฑ…์œผ๋กœ ์ธํ•ด ์ผ์–ด๋‚œ ์—๋Ÿฌ์ด๋‹ค.


๐Ÿ‘ ํ•ด๊ฒฐ๋ฒ•


1๏ธโƒฃ decorator๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • view์— csrf ์ ์šฉํ•˜์ง€ ์•Š๊ธฐ

๋‹จ์ˆœํ•˜๊ฒŒ csrf ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค. ๋ฐฉ๋ฒ•์€ ์•„์ฃผ ๊ฐ„๋‹จํ•˜๋‹ค. views.py์— ์›ํ•˜๋Š” view์— decorator๋ฅผ ๋‹ฌ์•„์ฃผ๋ฉด ๋œ๋‹ค.

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def search(request):

    return HttpResponse('success')

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•ด๊ฒฐ๋˜์ง€๋งŒ, ๋ญ”๊ฐ€ ๋ณด์•ˆ์ƒ ๋ญ”๊ฐ€ ์ฐœ์ฐœํ•˜๋‹ค.. ๊ทธ๋ž˜์„œ ๋‹ค์Œ ๋ฐฉ๋ฒ•์„ ์ค€๋น„ํ–ˆ๋‹คโ—๏ธ


2๏ธโƒฃ html ํŒŒ์ผ header๋ถ€๋ถ„์— csrf token ์ƒ์„ฑํ•˜๊ธฐ

์ด ๋ฐฉ๋ฒ•์€ django ๊ณต์‹ ๋ฌธ์„œ(๋ณด๋Ÿฌ๊ฐ€๊ธฐ)์— ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ajax๋ฅผ ์‚ฌ์šฉํ•˜๋Š” html ํŒŒ์ผ์˜ header ๋ถ€๋ถ„์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

<script>
  function getCookie(name) {
      var cookieValue = null;
      if (document.cookie && document.cookie !== '') {
          var cookies = document.cookie.split(';');
          for (var i = 0; i < cookies.length; i++) {
              var cookie = cookies[i].trim();
              // Does this cookie string begin with the name we want?
              if (cookie.substring(0, name.length + 1) === (name + '=')) {
                  cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                  break;
              }
          }
      }
      return cookieValue;
  }
  var csrftoken = getCookie('csrftoken');

  function csrfSafeMethod(method) {
      // these HTTP methods do not require CSRF protection
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
  }
  $.ajaxSetup({
      beforeSend: function(xhr, settings) {
          if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
              xhr.setRequestHeader("X-CSRFToken", csrftoken);
          }
      }
  });
</script>

๋Œ€๊ฐ• ๋ณด๋ฉด ํ† ํฐ์„ ๋งŒ๋“ค๊ณ  ajax์— ๋ฏธ๋ฆฌ ์„ค์ •ํ•ด์ฃผ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ํ•„์š”ํ•œ ์‚ฌํ•ญ์€ ๋‹น์—ฐํžˆ jquery๋ฅผ ๋จผ์ € ๋ถˆ๋Ÿฌ์™€์•ผ ํ•œ๋‹ค.


โž• 2021/04/08 ๋‚ด์šฉ ์ถ”๊ฐ€

ํ›„์— ์œ„์˜ ๋ฐฉ๋ฒ•์œผ๋กœ๋„ ๋๋‹ค๊ฐ€ ์•ˆ ๋๋‹ค๊ฐ€ ํ•˜๋‹ค๊ฐ€ ๊ฒฐ๊ตญ ๋˜ ์•ˆ๋˜๊ธธ๋ž˜ ๊ฐ„๋‹จํ•œ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜๋‹ค.

<script>
  $.ajaxSetup({
    headers: { "X-CSRFToken": '{{csrf_token}}' }
  });
</script>

๋‹จ์ˆœํžˆ ์ด ๋ถ€๋ถ„๋งŒ html ํŒŒ์ผ์˜ header ๋ถ€๋ถ„์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด๋œ๋‹ค... ์ด๊ฒƒ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„ ๋˜ ๋‚ ๋ฆฐ๊ฑฐ ๋„ˆ๋ฌด ํ™”๋‚˜๋„ค๐Ÿคฌ


๐Ÿ˜‚ ๋งˆ๋ฌด๋ฆฌ


์ฒ˜์Œ ๋ฐฐ์šธ ๋•Œ์—๋Š” ์–ด๋–ค ๊ฒƒ์ธ์ง€๋„ ๋ชจ๋ฅด๊ณ  ๋‹จ์ˆœํžˆ ์—๋Ÿฌ๋งŒ ์—†์• ๋ ค๊ณ  ์‚ฌ์šฉํ–ˆ์—ˆ๋Š”๋ฐ, ๋‹ค์‹œ ๋ณด๋‹ˆ ๊ฐํšŒ๊ฐ€ ์ƒˆ๋กญ๊ณ  ์˜คํžˆ๋ ค ๋” ๊ธฐ์–ต์— ๋‚จ๊ฒŒ ๋˜์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด ๋จธ๋ฆฌ๋ฅผ ๋„ˆ๋ฌด ๋ฏฟ์ง€ ๋ง์ž. ์˜ค๋Š˜๋„ ํฌ์ŠคํŒ…... ํฌ์ŠคํŒ…...๐Ÿง‘โ€๐Ÿ’ป


reference

'python > django' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[django] mysql + docker-compose  (1) 2022.12.25
[django] ajax๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ ์ฃผ๊ณ ๋ฐ›๊ธฐ  (0) 2021.03.20