Django3系において、Ajaxでcsrftokenをviews.pyに渡す方法です。
DjangoでStripe決済処理のチェックアウトを行う際にcsrftokenをviews.pyに渡す必要がありました。
しかし、csrftokenを用意していなかったためエラーが発生。CSRFトークンが見つからないよ!というエラーが出ていました。
これはDjangoがデフォルトではミドルウェアによってCSRF対策をしているためです。
そちらの解決方法です。
公式に載ってた
『Django、AJAXでcsrftokenを設定する方法』function getCookie(name) {
let cookieValue = null;
if (document.cookie && ….(省略
}
const csrftoken = getCookie(‘csrftoken’);関数作って渡す!
『Cross Site Request Forgery protection』https://t.co/CB5NWsupnr
— りーず Leez(そーめる) (@so_meru) December 18, 2020
なんと普通にDjangoの公式に対応方法が書いてありました。
日本語訳は
https://docs.djangoproject.com/ja/3.1/ref/csrf/
こちらです。(Djangoのバージョンは3.1の場合です)
このJavaScriptのコードを張り付けて、CSRFトークンを取得します。
function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const 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; } const csrftoken = getCookie('csrftoken');
csrftokenを取得するJavaScriptのコード。checkout.htmlに上記のコードを入れる。
Django公式からコピペでOKです。
このように、checkout.htmlの中にJavaScriptで csrftokenという変数を作ってあげます。
あとは、AjaxでPOST送信する際の処理、 checkout.html で
fetch("/create-checkout-session", { method: "POST", mode: 'same-origin', // Do not send CSRF token to another domain. headers: { 'X-CSRFToken': csrftoken, }, })
checkout.htmlの続き。X-CSRFTokenにcsrftoken変数を渡す。
このようにしてcsrftokenを送ってあげると動きます。
checkout.htmlでボタンを押してStripeの決済ページに進むことが出来るはずです。
以上で完了です。
・おまけ。Djangoに実装するときのポイントなど
checkout.htmlから/create-checkout-sessionというパスにPOST出来るようにするには、
views.pyで
def create_checkout_session(request): if request.method == 'POST': try: checkout_session = stripe.checkout.Session.create( (以下省略)
まず、このように関数を定義します。
関数名にハイフンは使えないようなのでアンダーバーにしています。
そして、urls.pyで
urlpatterns = [ (省略) path('create-checkout-session', views.create_checkout_session, name="create-checkout-session"), ]
このように書いてあげると /create-checkout-session というパスで
views.pyのdef create_checkout_session(request):
にアクセスできるようになります。
Stripeの決済は、
https://stripe.com/docs/payments
こちらの「Accept a payment」
https://stripe.com/docs/checkout/integration-builder
上記のページのPython(Flask)のコードをDjango用に書き換えました。
jsonは
views .pyでimport json
from django.http.response import JsonResponseをインポートして
jsonifyをJsonResponseに書き換える。
— りーず Leez(そーめる) (@so_meru) November 13, 2020
jsonfyはDjangoでは使えないので、jsonResponseを使いました。
以上、Djangoにおいて、Ajaxでcsrfトークンをviews.pyに渡す方法でした。
何の参考になれば幸いです。
※こちらの記事は動作の安全性を保障するものではありません。実装は自己責任でお願いします。
なにか間違い等ございましたら @so_meru までリプライ等でご連絡いただけると大変助かります。