Zag*_*ags 6 django cookies csrf django-csrf angularjs
在Django中,当CSRF_COOKIE_HTTPONLY设置设置为True时,CSRF cookie获得了httponly标志,这从安全角度来看是理想的,但是打破了将此cookie添加到httpProvider的标准角度解决方案,如下所示:
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
Run Code Online (Sandbox Code Playgroud)
通过Django 1.9,有一个解决方法,你可以通过将它放在模板中直接将cookie传递给应用程序:
<script>
window.csrf_token = "{{ csrf_token }}";
</script>
Run Code Online (Sandbox Code Playgroud)
把它放在角度应用程序中:
angularApp.config(["$httpProvider", function($httpProvider)e {
$httpProvider.defaults.headers.common["X-CSRFToken"] = window.csrf_token;
}]
Run Code Online (Sandbox Code Playgroud)
不幸的是,这对于Django 1.10+中的单页角度应用程序不起作用,因为CSRF cookie在每次请求后都会更改.如何通过CSRF_COOKIE_HTTPONLY设置从Angular发送到Django 1.10+的帖子请求?
注意:禁用CSRF保护是不可接受的答案.
小智 1
Django对此有一个记录的解决方案。即使启用了 CSRF_COOKIE_HTTPONLY,只要 CSRF 令牌位于 DOM 中,任何 Javascript 都可以从 DOM 获取 CSRF 令牌。
第 1 步:我添加一个标签,让 Django 中间件将 csrf 令牌放入 DOM
# Django put CSRF token to DOM
{% csrf_token %}Run Code Online (Sandbox Code Playgroud)
步骤 2:实现 HttpInterceptor 以从 DOM 获取 csrf
import { Injectable } from '@angular/core';
import { HttpEvent, HttpRequest, HttpHandler, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class DjangoCSRFInterceptor implements HttpInterceptor {
intercept(httpRequest: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = (
document.querySelector('[name=csrfmiddlewaretoken]') as HTMLInputElement
).value;
return httpRequest.clone({ headers: httpRequest.headers.set('X-CSRFToken, token) });
}
}
Run Code Online (Sandbox Code Playgroud)
第 3 步:将 HttpInterceptor 添加到 Angular 模块提供程序中
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: DjangoCSRFInterceptor, multi: true }
]Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1127 次 |
| 最近记录: |