djangoで二重サブミットを制御するデコレータを作って見た

djangoで二重サブミットを制御するデコレータを作って見た

以前書いた記事
  ・djangoで自作デコレータを使ってみる
  ・djangoで多重submitを制御する

プログラム

【ビュー】


import uuid
from django.shortcuts import render
from functools import wraps

def get_token(request):
    token = str(uuid.uuid4())
    request.session['token'] = token
    return token

def submit_check(func):
    @wraps(func)
    def check_token(request, *args, **kwargs):
        if request.method == 'POST':
            token_in_request = request.POST.get('token')
            token_in_session = request.session.pop('token', '')

            if not token_in_request or\
               not token_in_session or\
               token_in_request != token_in_session:
                raise Exception("不正なリクエスト")
            else:
                return func(request, *args, **kwargs)
        else:
            return func(request, *args, **kwargs)
    return check_token

@submit_check
def index(request):
    context = {
        'token': get_token(request)
    }
    return render(request, 'myapp/index.html', context)

【テンプレート】


<form action="{% url 'myapp:index' %}" method="GET">
    <button type="submit">GET</button>
</form>
<form action="{% url 'myapp:index' %}" method="POST">{% csrf_token %}
    <input type="hidden" name="token" value="{{ token }}">
    <button type="submit">POST</button>
</form>