我如何将Angular 2+应用程序中的请求中的cookie发送到Django后端,在那里我以cookie的形式访问它们?

时间:2018-07-31 16:26:13

标签: django angular cookies angular6

Angular在浏览器中设置cookie,但是当我向Django发送POST请求时, request.COOKIES在Django视图中为空。我需要将CSRF cookie发送回Django,以cookie的形式存储和访问。

注意:仅按以下方式在标头中发送CSRF(或使用任何其他标头技术)不起作用(Django仍然记录“禁止:未设置CSRF cookie”)

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { SharedService } from '../../shared.service';
import { CookieService } from 'ngx-cookie-service';

@Injectable({
  providedIn: 'root'
})
export class EmailService {
// http options used for making any writing API calls with csrf token
private httpOptions: any;
csrfToken;

constructor(private http: HttpClient, private cookieService: CookieService) {
  // Set the csrf token
  this.http.get(SharedService.contactEmailUrl).subscribe((data) => (this.csrfToken = data['csrfToken']), (error1) => console.log(error1));
}

sendMailgunContactMessage(payload) {
  // Configure CSRF token header options
  this.httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-CSRFToken': this.csrfToken,
      'x-csrftoken': this.csrfToken,
      'X-XSRF-TOKEN': this.csrfToken,
      'XSRF-TOKEN': this.csrfToken,
      'X-CSRF': this.csrfToken,
      csrfmiddlewaretoken: this.csrfToken,
      csrftoken: this.csrfToken
    }),
    withCredentials: true
  };

  let body = {
    csrfmiddlewaretoken: this.csrfToken,
    content: payload
  };

  this.cookieService.set('csrfcookie', this.csrfToken);
  return this.http.post(SharedService.contactEmailUrl, body, this.httpOptions);
}
}

2 个答案:

答案 0 :(得分:0)

如果您谈论CSRF允许将POST发送到后端,则可以在将数据发送到django时将其传递到标头中

检查以下示例:

https://docs.djangoproject.com/en/2.0/ref/csrf/#setting-the-token-on-the-ajax-request

http://django-angular.readthedocs.io/en/latest/csrf-protection.html

答案 1 :(得分:0)

确保在每个请求中都有cookie

  1. 我将ngx-cookie-service添加到我的项目https://github.com/7leads/ngx-cookie-service#readme

  2. 然后我创建了一个拦截器csrf.interceptor.ts

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import { Observable } from 'rxjs';

@Injectable()
export class CsrfInterceptor implements HttpInterceptor {
    csrfToken: any;

    constructor(
        private cookieService: CookieService
    ) {
        this.csrfToken = this.cookieService.get('csrftoken');
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if (this.csrfToken) {
            const addCsrf = req.clone({
                headers: req.headers.set('X-CSRFToken', this.csrfToken)
            });
            return next.handle(addCsrf);
        } else {
            return next.handle(req);
        }
    }
}

最后,在您的app.module中,您需要提供拦截器:

// angular core
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { CookieService } from 'ngx-cookie-service';

// services
// components
@NgModule({
    declarations: [
        ...
    ],
    imports: [
        HttpClientModule
    ],
    providers: [
        CookieService,
        {
            provide: HTTP_INTERCEPTORS,
            useClass: CsrfInterceptor,
            multi: true
        }
    ],
    bootstrap: [
        AppComponent
    ]
})
export class AppModule { }