1

我一直在为 Django 和 Angular 之间的配置而苦苦挣扎,但我遗漏了一些东西。推荐的方法是什么?

Angular 有一些 XSRF 保护,但是自从 AngularJS 和我发现很多过时的信息或手册之后它已经改变了。Django 使用了一些默认值,但它们在 Angular 中表现不佳。

在 DRF 和 Angular 之间解决 CSRF 的包含电池的方法是什么?

4

1 回答 1

0

HTTP 指南中解释了 Angular 推荐的方法,但对于我们中的一些人来说,它有一些棘手的步骤。幸运的是,在最新版本的 Angular 中,您只需要进行少量更改。一旦设置好,所有默认/推荐的 CSRF 中间件都会表现良好。有一些特定于 DRF 的信息以及对Django 官方文档的参考

现在对我有用的最小更改(Django 2.1、Angular 6 和最新版本的依赖项)如下

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'

警告!请记住,cookie 名称区分大小写。我在那里浪费了很多时间:(

请注意,JavaScript 应该可以访问 CSRF cookie,因此httpOnly不应将 flag 设置为True.

在这里,我假设您已经拥有一个功能性身份验证系统并且正在使用两者django.contrib.sessions.middleware.SessionMiddleware(通常您会在变量中django.middleware.csrf.CsrfViewMiddleware找到这些模块)。MIDDLEWAREsettings.py

角边

然后,在角侧激活 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(至少:连字符到下划线和HTTP_前缀)。前面的示例应该与 的默认值匹配HTTP_X_CSRFTOKEN。默认的CSRF_COOKIE_NAMEDjango 设置是csrftoken(小写)。

如果您在自定义命名方面遇到问题,请检查 Angular 插入的实际标头(使用浏览器的开发人员工具),您可以通过调试request.META

于 2018-12-17T11:02:20.177 回答