web-dev-qa-db-ja.com

Django @csrf_exemptでは、request.sessionは常に空です

私はDjangoで立ち往生しています。誰かが私を助けてくれれば本当に感謝しています。

サードパーティのAPIのエントリポイントが必要です。そこで、ビューを作成して@csrf_exemptで装飾しました

今問題は、以前に設定したセッション変数にアクセスできないことです。 編集-ユーザーが既にログインしているかどうかを知るために、ユーザーのメールなどの複数のセッション変数を設定しました。サードパーティAPIを呼び出す前にセッションを使用できました。サードパーティAPIが応答を送信すると、応答しません。 t CSRFトークンを送信するため、そのビューをcsrfから除外します。有効な応答を受け取ったら、データベースを更新します。これを行うには、セッションがないために失ったユーザーのメールIDを知る必要があります変数。

ppConfirmPaymentProcessは、このサードパーティAPIから送信されたPOSTデータを処理する別の関数です。すべてが正常に機能しており、csrf_exemptも正常に機能していますが、request.session["foo"]このリクエスト。誰か助けてくれますか?

@csrf_exempt
def ppConfirmPayment(request):
    print(request.session, "=======================================")
    for key, value in request.session.items():
        print('{} => {}'.format(key, value))
    return ppConfirmPaymentProcess(request)
8
GKV

Django自体を使用して解決しました。セッションIDの操作やデータベースとの相互作用はありません。

Step1:サードパーティのAPIを呼び出します

@login_required
def thirdPartyAPICall(request):
    #do some stuff and send a request to 3rd party

Step2:ビューでサードパーティからのコールバックを受信します。 csrf_exemptではなくlogin_requiredサードパーティがCSRFトークンとセッションなしでアプリケーションにリクエストを送信できるようにします。それは私のアプリへのエントリポイントのようなものです。このcallBackViewで何らかのアクションを実行し、これが本当にサードパーティからの有効な応答であるか、または誰かがシステムをハッキングしようとしているのかどうかを確認します。例えば。 CHECKSUMまたはTXNIDなどを確認してから応答ディクショナリを作成し、アプリ内でHttpResponseRedirectを使用して別のHTTP応答を別のリソースに送信し、関連するGETパラメーターをそれ。

この特定の手順により、以前のセッションが復元され、サードパーティから送信されたリクエストを処理するための関連データが得られ、sessionをリクエストに戻しました。

@csrf_exempt
def callBackView(request):
     if request.POST["CHECKSUM"] == myCalCulatedCheckSum:
          foo = True
     else:
          foo = False
     return HttpResponseRedirect("TEST.HTML" +"/" + str(foo))

前に述べたように、セッションを保存する必要がないので、この方法が一番好きです。Djangoがそれを行います。

0
GKV

ドキュメントを参照してください: https://docs.djangoproject.com/en/3.0/topics/http/sessions/

Djangoは、セッションキーにタグ付けされたセッションデータを次のように保存します。
{"session_key":sdfkjdsbks、 "user_email": "[email protected]"}

ユーザーの電子メールを保存しているときにrequest.session.session_keyを印刷してコピーし、ビュー内に同じsession_keyが再度表示されるかどうかを確認します。

そうでない場合は、コピーしたセッションキーを使用して、ビュー内の前のセッションを強制的にロードできます。

from importlib import import_module
from Django.conf import settings

@csrf_exempt
def ppConfirmPayment(request):

    engine = import_module(settings.SESSION_ENGINE)

    # copy the old_session_key value from request when you saved user email
    request.session = engine.SessionStore(old_session_key)

    print(request.session, "=======================================")
    for key, value in request.session.items():
        print('{} => {}'.format(key, value))
    return ppConfirmPaymentProcess(request)

これが機能する場合は、session_keyをサードパーティAPIに送信し、Cookie内の同じセッションキーまたは後続の呼び出しのデータを送信するように要求できます。そして、セッションキーをキャプチャし、ビュー内にセッションを強制的にロードします。

1
Rahul Sinha