在 Django Rest Framework + Angular 应用程序中进行 CSRF 保护的推荐方法是什么?
What is the recommended way to have CSRF protection in a Django Rest Framework + Angular application?
我一直在为 Django 和 Angular 之间的配置而苦苦挣扎,但我遗漏了一些东西。推荐的做法是什么?
Angular 有一些 XSRF 保护,但是自 AngularJS 以来它已经改变了,我发现了很多过时的信息或手册。 Django 使用一些默认值,但它们在 Angular.
下表现不佳
解决DRF与Angular之间CSRF的含电池方式是什么?
Angular 推荐的方法在 HTTP Guide but, for some of us, it has some tricky steps. Fortunately, in recent versions of Angular, you need minimal changes. And all the default/recommended CSRF middleware behaves well once things have been set up. There is some information DRF-specific and also a reference to the Django official documentation
中有说明
现在对我有用的最小变化(Django 2.1、Angular 6 和 up-to-date 版本的依赖项)如下
Django 端
首先,您需要设置 Django 以按 Angular 期望的方式发送 cookie:
# settings.py
CSRF_USE_SESSIONS = False
CSRF_COOKIE_HTTPONLY = False # this is the default, and should be kept this way
CSRF_COOKIE_NAME = 'XSRF-TOKEN'
CSRF_HEADER_NAME = 'HTTP_X_XSRF_TOKEN'
Caution! Remember that cookie names are case sensitive. I lost a lot of time there :(
请注意,Javascript 应该可以访问 CSRF cookie,因此 httpOnly
标志不应设置为 True
。
在这里,我假设您已经拥有一个功能验证系统并且正在使用 django.contrib.sessions.middleware.SessionMiddleware
和 django.middleware.csrf.CsrfViewMiddleware
(通常您会在settings.py
).
Angular边
然后,在angular端激活CSRF:
# app.module.ts
import {HttpClientModule, HttpClientXsrfModule} from '@angular/common/http';
...
@NgModule({
imports: [
// ...
HttpClientModule,
HttpClientXsrfModule,
]
// ...
如果您不想更改 CSRF Header 和 Cookie 的 Django 默认名称,您可以在 Angular 端更改它们,方法是更改 HttpClientXsrfModule,
行:
HttpClientXsrfModule.withOptions({
cookieName: 'csrftoken',
headerName: 'X-CSRFTOKEN',
}),
我还没有完全测试过这个配置。请记住,在 Django 端,您必须稍微更改 CSRF_HEADER_NAME
(至少:hyphen-to-underscores 和 HTTP_
前缀)。前面的示例应该匹配 HTTP_X_CSRFTOKEN
的默认值。默认的 CSRF_COOKIE_NAME
Django 设置是 csrftoken
(小写)。
如果您对自定义命名有疑问,请检查 Angular 插入的实际 headers(使用您浏览器的开发人员工具),您可以仔细检查您在 Django 中是如何接收它们的调试 request.META
的内容
我一直在为 Django 和 Angular 之间的配置而苦苦挣扎,但我遗漏了一些东西。推荐的做法是什么?
Angular 有一些 XSRF 保护,但是自 AngularJS 以来它已经改变了,我发现了很多过时的信息或手册。 Django 使用一些默认值,但它们在 Angular.
下表现不佳解决DRF与Angular之间CSRF的含电池方式是什么?
Angular 推荐的方法在 HTTP Guide but, for some of us, it has some tricky steps. Fortunately, in recent versions of Angular, you need minimal changes. And all the default/recommended CSRF middleware behaves well once things have been set up. There is some information DRF-specific and also a reference to the Django official documentation
中有说明现在对我有用的最小变化(Django 2.1、Angular 6 和 up-to-date 版本的依赖项)如下
Django 端
首先,您需要设置 Django 以按 Angular 期望的方式发送 cookie:
# settings.py
CSRF_USE_SESSIONS = False
CSRF_COOKIE_HTTPONLY = False # this is the default, and should be kept this way
CSRF_COOKIE_NAME = 'XSRF-TOKEN'
CSRF_HEADER_NAME = 'HTTP_X_XSRF_TOKEN'
Caution! Remember that cookie names are case sensitive. I lost a lot of time there :(
请注意,Javascript 应该可以访问 CSRF cookie,因此 httpOnly
标志不应设置为 True
。
在这里,我假设您已经拥有一个功能验证系统并且正在使用 django.contrib.sessions.middleware.SessionMiddleware
和 django.middleware.csrf.CsrfViewMiddleware
(通常您会在settings.py
).
Angular边
然后,在angular端激活CSRF:
# app.module.ts
import {HttpClientModule, HttpClientXsrfModule} from '@angular/common/http';
...
@NgModule({
imports: [
// ...
HttpClientModule,
HttpClientXsrfModule,
]
// ...
如果您不想更改 CSRF Header 和 Cookie 的 Django 默认名称,您可以在 Angular 端更改它们,方法是更改 HttpClientXsrfModule,
行:
HttpClientXsrfModule.withOptions({
cookieName: 'csrftoken',
headerName: 'X-CSRFTOKEN',
}),
我还没有完全测试过这个配置。请记住,在 Django 端,您必须稍微更改 CSRF_HEADER_NAME
(至少:hyphen-to-underscores 和 HTTP_
前缀)。前面的示例应该匹配 HTTP_X_CSRFTOKEN
的默认值。默认的 CSRF_COOKIE_NAME
Django 设置是 csrftoken
(小写)。
如果您对自定义命名有疑问,请检查 Angular 插入的实际 headers(使用您浏览器的开发人员工具),您可以仔细检查您在 Django 中是如何接收它们的调试 request.META