How to add CSRF token to Angular 8 post request from Django 2.2

邮差的信 提交于 2019-12-10 17:15:13

问题


I have an application with Django backend and angular frontend. Now, these are connected with each other, I can get data from Django and show in Angular. As well Send a post request to Django.

But the issue is with CSRF token in Django. I disable the CSRF middleware in Django and the request process completely, but I know this is insecure.

Method to do a post request.

loadQuestion(id): Observable<any> {
    const body = {'choice': 'teseted with post method'};
    return this.http.post(this.baseUrl + id + '/vote', {headers: this.header, withCredentials: true, });
  }

I did some changes according to this link.

HttpClientXsrfModule.withConfig({ cookieName: 'csrftoken', headerName: 'X-CSRFToken' })

but I get this error.

app.module.ts:26 Uncaught TypeError: _angular_common_http__WEBPACK_IMPORTED_MODULE_3__.HttpClientXsrfModule.withConfig is not a function

So I changed it based on this Link

HttpClientXsrfModule.withOptions({ cookieName: 'csrftoken', headerName: 'X-CSRFToken' })

This is my Django function to return data, as I said when I disabled CSRF middleware is working fine So I should fix the CSRF issue and passing it with Angular request.

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=4)
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return HttpResponse("You didn't select a choice.")
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponse(request)

Middleware code that I commented:

'django.middleware.csrf.CsrfViewMiddleware'

and the error is CSRF verification failed. Request aborted.

Update

I use the CORS Origin, here is my Django config

CORS_ORIGIN_ALLOW_ALL = True

CSRF_COOKIE_SECURE = False
CSRF_USE_SESSIONS = False

CORS_ORIGIN_ALLOW_ALL = True

CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'X-CSRFToken',
    'x-csrftoken',
    'X-XSRF-TOKEN',
    'XSRF-TOKEN',
    'csrfmiddlewaretoken',
    'csrftoken',
    'X-CSRF'
)

CORS_ALLOW_CREDENTIALS = True

回答1:


You can wrap your view with csrf_exempt

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def vote():
...

"If you’re using AngularJS 1.1.3 and newer, it’s sufficient to configure the $http provider with the cookie and header names:"

httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';



回答2:


So I use this library called ngx-cookie, link for it. Install it & then add this in you service.ts.

import {CookieService} from 'ngx-cookie';

constructor(private http: HttpClient, private _cookieService: CookieService) {
  let csrf = this._cookieService.get("csrftoken");
  if (typeof(csrf) === 'undefined') {
    csrf = '';
  }
  this.httpOptions = {
    headers: new HttpHeaders({'X-CSRFToken': csrf}),
  };
}

public postCall(payload){
  return this.http.post('/yourapi/', payload, this.httpOptions);
}

Explaination:

let csrf = this._cookieService.get("csrftoken");

this line is getting the csrf token from the cookie

 headers: new HttpHeaders({'X-CSRFToken': csrf}),

this line adds that value of csrf into the HttpHeaders.

this.http.post('/yourapi/', payload, this.httpOptions);

while making the post call we're using these headers



来源:https://stackoverflow.com/questions/58266828/how-to-add-csrf-token-to-angular-8-post-request-from-django-2-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!