DullCodes’s diary

programming,c++,python,MachineLearning,Math,Django,Competitive

初めてのDjango 9 - form POST

form input

必要なものは2ファイル

html にフォームを追加

{% extends "base.html" %}

{% block index %}
<div>
  <h1>INPUT FORM</h1>

  <!-- 送信フォーム -->
  <form action="" method="POST">
    <!-- form の name は POSTの中身受け取るときに大事 -->
    <input type="text" size="20" name="some_text">
    <input type="submit" value="submit">
  </form>

  <div>
    {{ var }}
  </div>
  
</div>
{% endblock %}

データの送信先に post メソッドを用意

from django.shortcuts import render
from django.views import View


class HelloView(View):
    def get(self, request, *args, **kwargs):
        ctx = {
            'message': 'hello world'
        }
        return render(request, 'myapp/index.html', context=ctx)

    # Viewクラスに postメソッドを用意
    def post(self, request, *args, **kwargs):
        """
        すべてのデータは request に入ってここに来るので
        どんなデータが送信されたかは request を表示すればわかる
        """
        print(request)
        print(request.GET)
        print(request.POST)

        ctx = {
            'var': request.POST['some_text']
        }
        return render(request, 'myapp/index.html', context=ctx)

実行

f:id:DullCodes:20200304001246p:plain
django input form

f:id:DullCodes:20200304001404p:plain
django input form typed

SUBMIT!!

送信エラー?

f:id:DullCodes:20200304001442p:plain
django form post CSRF error

はい?

というわけでCSRFの勉強

CSRFとは

クロスサイトリクエストフォージェリCSRF)とは、Webアプリケーションに存在する脆弱性、もしくはその脆弱性を利用した攻撃方法のことです。掲示板や問い合わせフォームなどを処理するWebアプリケーションが、本来拒否すべき他サイトからのリクエストを受信し処理してしまいます。


docs.djangoproject.com

へぇーというわけでCSRFは対策しなきゃいけないんbr> 攻撃方法はおそらくとんでもなく多岐に渡るだろうが、Djangoではすごく簡単に対策できる

csrf_token

現在推奨されている対策としてはワンタイムトークンを利用する方法になります。CSRF対策はリクエスト先では、セッションに保存したトークンと送信されたトークンが一致するか確認を行い、一致しない場合は不正なリクエストとして扱います。

{% extends "base.html" %}

{% block index %}
<div>
  <h1>INPUT FORM</h1>

  <form action="" method="POST">
    <!-- これ!-->
    {% csrf_token %}
    <input type="text" size="20" name="some_text">
    <input type="submit" value="submit">
  </form>

  <div>
    {{ var }}
  </div>
  
</div>
{% endblock %}

これですべてのcsrfを対策できるわけでは無いと思うけどとりあえず色々
やってくれてるらしいということで再度SUBMIT!!!

結果

f:id:DullCodes:20200304002152p:plain
django input form submitted message

素晴らしい なんと簡単にできるのか
あとは request の中身をみて終了

Requestの中身

f:id:DullCodes:20200304002208p:plain
show bash from request content POST

request にはこんなものが入っている

request

<WSGIRequest: POST '/myapp/'>

WSGI というわけのわからん用語が
そういえばDjango の project 作ったときに wsgi.pyというファイルが出来ている
が、これはまたいつか

request.GET

<QueryDict: {}>

GETでは送信していないので request の中身は当然空っぽ

request.POST

<QueryDict: {
    'csrfmiddlewaretoken': ['8HQsMizqLCIrpO06P8nZoKdwCL3zfmqaaAwQPslEdLhY1IquAJmXfoXTacquB756'],
    'some_text': ['Hello Input World']
}>

csrf 対策にこのtokenってやつを受け渡しして何かの認証をしてるとかしてないとか

form some_text に 'Hello Input World' が入っている
django側で出力するときは request.POST['some_text'] で簡単に使える
まー楽ちん

まとめ

html に フォームを作って、csrf_tokenを忘れずに、view関数で受け取って、適切に処理