How to get CSRF token from mobile apps when CSRF_U

2019-09-16 03:09发布

Good evening everybody,

As a student group, we are developing an API using Django 1.11.2 and we would like to consume our API from mobile apps (such as Android applications).

Currently, we are struggling getting the CSRF token from mobile applications, here's the background :

  • We are using CSRF_USE_SESSIONS = True. From what I understand from the Django CSRF documentation, the token is stored in the session instead of a cookie.
  • We are using the SessionMiddleware in which the SESSION_ENGINE is configured as 'django.contrib.sessions.backends.signed_cookies'
  • For the big authentication part, we are using class-based views.
  • In multiple templates, we are using {% csrf_token %} into forms in order to protect them during POST requests.

Everything works great when consuming the API from a non-mobile web client. However, when consuming it from an Android application, we face multiple problems. What we tried so far was - during a GET request - getting the CSRF token from the session and sending it through Accept: 'application/json' :

class Login(LoginView):

form_class = AuthenticationForm
template_name = 'users/login.html'

def get(self, request, *args, **kwargs):
    if request.META.get('HTTP_ACCEPT') == 'application/json':
        csrftoken = request.session.get(CSRF_SESSION_KEY)
        return JsonResponse({
            'csrf-header-name': 'X-CSRFToken',
            'csrf-token': csrftoken
        }, status=200)
    return super().get(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
    if request.META.get('HTTP_ACCEPT') == 'application/json':
        form = self.get_form()
        if not form.is_valid():
            print(form.errors.as_text())
            return JsonResponse({'error': form.errors.as_text()}, status=400)
    return super().post(request, *args, **kwargs)

The problem is that we can't get the session from 'application/json', it seems that the session cookie isn't sent (but it does work well when not using 'application/json'). Thus, the 'csrf-token' in the JSONResponse simply returns a null value.

Have you ever faced this case ? Do you have any recommendations to get the CSRF token when storing it in sessions ?

1条回答
神经病院院长
2楼-- · 2019-09-16 04:08

You could try using the get_token method.

from django.middleware.csrf import get_token

csrftoken = get_token(request)
查看更多
登录 后发表回答