0

Good evening,

Following this discussion, we are facing a new problem. We are trying to make a POST request (login) work on Android using the Volley library to make HTTP requests. The /login/ works well on Postman or Advanced REST Client, but it doesn't when using Volley. We have seen many other persons facing this problem and trying to find an answer on SO, but the only answer was to disable CSRF and we really don't want to do this.

On Postman, the response is 200 OK.
On Android Volley, the response is 403 forbidden : CSRF cookie not set.

Since we set CSRF_USE_SESSIONS as True, it doesn't make sense for us.

  • CSRF_USE_SESSIONS is True in Django
  • The library used to make HTTP requests on Android is Volley
  • We don't want to disable CSRF protection/middleware (I'm pointing this because many answers in other posts talking about this problem suggest to disable CSRF, but we are using it for both web client and mobile apps)

Here is the Java request :

    private void loginPost(final String csrf) {
    RequestQueue queue = Volley.newRequestQueue(getActivity());
    String url = "https://api.ourapi.com/login/";


    JSONObject object = new JSONObject();

    try {
        object.put("username", "hello");
        object.put("password", "world");

        System.out.println(object);
    } catch (JSONException e) {
        Log.d("Dude", "RIIIIIIIIIIIIIIIIIIIP");
    }

    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
            (Request.Method.POST, url, object, new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    // response
                    System.out.println("######################################");
                    System.out.println(response);
                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    // TODO Auto-generated method stub
                    System.out.println(error);
                }
            }
            ) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String>  params = new HashMap<String, String>();

            params.put("Accept", "application/json");
            params.put("X-CSRFToken", csrf);

            System.out.println(params);
            return params;
        }
    };
    queue.add(jsonObjectRequest);
}

Here is the Django Login class-based view :

class Login(LoginView):

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

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)

We think that we are missing something in the Volley request headers or somewhere else. Can you guys help us ?

EDIT:

Here are our CSRF settings:

  • CSRF_COOKIE_AGE = None
  • CSRF_COOKIE_DOMAIN = '.ourapi.com'
  • CSRF_COOKIE_HTTPONLY = True
  • CSRF_COOKIE_SECURE = True
  • CSRF_USE_SESSIONS = True

1 Answer 1

1

Self answer, here !

I kind of misunderstood how CSRF and session cookies work in Django. In the process_view function of the CsrfViewMiddleware, the reason message 403 forbidden - CSRF cookie not set is triggered when the CSRF token is None (see here). The csrf_token value comes from the _get_token(request) method from the same class, but it seems that the value returned is None (see here).

All we had to do was simply sending the session cookie to the server with the CSRF token in the header as X-CSRFToken !

Sign up to request clarification or add additional context in comments.

1 Comment

Can you please share the exact context of X-CSRFToken

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.