0

This is a follow-up question to a question I asked yesterday: CSRF token in Angular 4 CLI from Django

I have a backend Django server and a frontend Angular app. I am trying to submit a form in Angular to the Django backend with a POST. The problem is with CSRF tokens.

This is the Django view:

#@csrf_exempt
def empty_form(request):
    if request.method=="POST":
        message = "Post"
    else:
        message = "Get"
    return JsonResponse({'message': message})

And this is the Angular component:

send_sample_form() {

  let d = new Date();
  d.setTime(d.getTime() + 1 * 24 * 60 * 60 * 1000);
  let expires:string = "expires=" + d.toUTCString();
  let cpath:string = '/';
  // this.cookieService.set('csrftoken', this.server_token, d, cpath, '127.0.0.1', false);
  this.cookieService.set('csrftoken', this.server_token);
  let my_headers = new HttpHeaders(
    {
      'X-CSRFToken': this.server_token
    }
  );
  this.http.post('http://127.0.0.1:8000/emptyform/',
        {'my_form': this.sample_form.value},
        {headers: this.server_token, withCredentials: true})
        .subscribe(
          (response) => {
            console.log(response);
          }
        );
}

When the Angular and Django are separate servers (localhost:4200 and 127.0.0.1:8000), the angular code does not get the CSRF token. When I run it in production mode and so there is only the Django server at 127.0.0.1:8000, now the Angular component is able to extract the CSRF token with:

ngOnInit() {
  this.http.get('http://127.0.0.1:8000/generate_token/', { observe: 'response' })
      .subscribe(
        (response) => {
          this.server_token = this.cookieService.get('csrftoken');
          console.log(this.server_token);
        });
}

But I have tried every possible version of the set() method of Cookie Service and am still getting a 403 from Django.

this.cookieService.set('csrftoken', this.server_token, d, cpath, '127.0.0.1', false); or this.cookieService.set('csrftoken', this.server_token);

To just check the Django server, I used Postman to send requests to my Django server. A get request gives me a CSRF token. And when I do a POST request, I need a CSRF cookie and a header 'X-CSRFToken' to get back a status 200 or I get a 403. So the Django server CSRF middleware seems to be working as it does give a 200 back when a request has a CSRF cookie and an XCSRFToken header.

I was trying to think if I can check in the Django view function if the request has the right CSRF cookie from the Angular frontend. I used 'csrf_exempt' to let the POST go through and was trying to find a way to extract the CSRF cookie and do a visual check but couldn't find a way to do that. Is there a way to extract a CSRF cookie in a Django view and print it out? Like?

print(request['csrftoken'])

The entire code is on my GitHub: https://github.com/shivkiyer/djangoangular

1 Answer 1

1

As simple as this: print(request.COOKIES['csrftoken'])

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

3 Comments

The CSRF token in the Django view is identical to what the Angular code outputs in console. But still I get a 403. So what else do I need to do? The is the error in the command line "Forbidden (CSRF token missing or incorrect.)"
Do you receive a correct x-csrftoken header as well?
I did a print(request.META) and there is no x-csrftoken. In my Angular, I am adding it with {headers: my_headers} option in the POST request with my_headers=new HttpHeaders('X-CSRFToken': this.server_token). Why is Angular not adding the header when this is specified?

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.