Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With Django @csrf_exempt, request.session is always empty

I am stuck in django and would really appreciate it if someone could help me.

I need to have an entry point for a 3rd party API. So I created a view and decorated it with @csrf_exempt

Now the problem is I am not able to access any session variables I set before. edit - I set multiple session variables like user email to know if a user is already logged in. I was able to use the session before calling the 3rd party API. When the 3rd party API sends a response, they don't send CSRF token hence I have exempt that view from csrf. Once I receive a valid response I want to update my database. To do that, I need to know the email id of the user which I lost since I don't have session variables anymore.

ppConfirmPaymentProcess is another function that processes the POST data sent by this 3rd party API. Everything is working fine, csrf_exempt is also working fine but I can't do request.session["foo"] with this request. Can someone please help?

@csrf_exempt
def ppConfirmPayment(request):
    print(request.session, "=======================================")
    for key, value in request.session.items():
        print('{} => {}'.format(key, value))
    return ppConfirmPaymentProcess(request)
like image 299
GKV Avatar asked May 15 '20 15:05

GKV


People also ask

What is Django request session?

A session is a mechanism to store information on the server side during the interaction with the web application. In Django, by default session stores in the database and also allows file-based and cache based sessions.

How does Django maintain session?

Django provides a session framework that lets you store and retrieve data on a per-site-visitor basis. Django abstracts the process of sending and receiving cookies, by placing a session ID cookie on the client side, and storing all the related data on the server side. So the data itself is not stored client side.

How does Django store data in session storage?

To use another cache, set SESSION_CACHE_ALIAS to the name of that cache. Once your cache is configured, you've got two choices for how to store data in the cache: Set SESSION_ENGINE to "django.contrib.sessions.backends.cache" for a simple caching session store. Session data will be stored directly in your cache.

What is CSRF exempt in Django?

by Harman Singh August 2, 2018 Csrf exempt is a cool feature of django which allows bypassing of csrf verification by django. By default, django check for csrf token with each POST request, it verifies csrf token before rendering the view.

How do I bypass the CSRF check in Django?

Instead, it explicitly calls the CSRF check when a user is successfully authenticated using SessionAuthentication. You can't bypass this check, nor should you. A regular Django view may not depend on the session, in which case a CSRF attack is not possible, and you can use csrf_exempt to indicate this.

What is CSRF_exempt in Django?

A regular Django view may not depend on the session, in which case a CSRF attack is not possible, and you can use csrf_exempt to indicate this. When you use SessionAuthentication, you are vulnerable to CSRF attacks, and you need the check to prevent attacks.

Where is the CSRF middleware in Django?

The CSRF middleware is activated by default in the MIDDLEWARE setting. If you override that setting, remember that 'django.middleware.csrf.CsrfViewMiddleware' should come before any view middleware that assume that CSRF attacks have been dealt with.


2 Answers

request.session will always be empty because it can only be initialized by your system and once the connection is closed, the session is destroyed. For new connection, new session is set. Since, your API endpoint is triggered directly by the third-party API without triggering any other endpoint, there is no way that the third party can set the sessions. Hence, request.session is empty.


Try storing the information in request.POST instead of request.session , which is more optimal way of getting information from third party.

like image 88
Damnik Jain Avatar answered Sep 28 '22 07:09

Damnik Jain


See Docs: https://docs.djangoproject.com/en/3.0/topics/http/sessions/

Django stores session data tagged to session key something like this:
{"session_key":sdfkjdsbks, "user_email":"[email protected]"}

Print and Copy the request.session.session_key when you are storing user email and check if you are getting the same session_key inside your view again.

if not then you can forcefully load the previous session inside view using the copied 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)

If this works then you can send session_key to 3rd party API and request them to send the same session key inside cookie or data in subsequent calls. And capture the session key and forcefully load the session inside your view.

like image 38
Rahul Sinha Avatar answered Sep 28 '22 07:09

Rahul Sinha