首页 > 解决方案 > 角度重置 csrf 令牌

问题描述

我正在使用 Angular 6,并且很难将 Django 的 csrf 与 Angular 的集成。我在这个线程中发现 Django 在登录时更改了令牌,因为我可以使用具有相同新会话的发布请求进行注册和登录,但在登录后不发布任何内容似乎是有道理的。

问题变成了我如何在登录时重置 csrf 令牌。现在在我的 Angular 应用程序中处理 csrf 的方式显示在我的应用程序模块的以下代码中:

import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { HttpModule, XSRFStrategy, CookieXSRFStrategy } from '@angular/http'

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { RegisterComponent } from './register/register.component';
import { LoginComponent } from './login/login.component';
import { AlertComponent } from './_directives/alert.component';
import { ProfileComponent } from './profile/profile.component';
import { AuthGuardService } from './_guards/auth-guard.service';
import { AlertService } from './_services/alert.service';
import { AuthService } from './_services/auth.service';
import { UserService } from './_services/User.service';

@NgModule({
  declarations: [
    AppComponent,
    RegisterComponent,
    LoginComponent,
    AlertComponent,
    ProfileComponent,
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    AppRoutingModule,
    HttpClientModule,
    HttpModule
  ],
  providers: [
    {
      provide: XSRFStrategy,
      useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

所以我的问题是,如何让我的应用程序在登录时重置值?(不一定专门登录,但我如何重置该值。)

标签: djangoangularpostcsrf

解决方案


好问题,这有点棘手,我的回答非常未经测试。但是,由于我找不到任何一篇文章/文章,因此在阅读了多个来源后,我决定记下我对这个问题的看法:

  • Django 和 Angular 默认都理解CSRF;因此,当您发出 POST 请求时,您无需手动设置显式 CSRF 标头值。
  • 这与说 jQuery 不同,您必须从 cookie 中找到CSRFToken,然后在标题中针对键“X-CSRFToken”设置它的值。
  • 但是,由于 Angular 不知道键的名称、从 cookie 中获取 CSRF 令牌的键的名称以及要在 Header 中设置的键的名称,因此您需要在 Angular中配置键名称。
  • 再一次:您只在此处设置键名,而不是值,因为 #1,Angular 会自动执行此操作。

    Angular 的 HttpClient 内置了对这种技术的客户端部分的支持。在 HttpClient 指南中了解更多信息。

您可以在Angular 1中按如下方式设置键名:

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

同样可以在Angular 2及更高版本中实现,如下所示:

bootstrap(AngularApp, [
      HTTP_PROVIDERS,
      provide(XSRFStrategy, {useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')})
    ]);
  • 是的,您是对的,在登录时,CSRFToken 的值会发生变化,您需要再次获取它,然后才能发出另一个 POST 请求。你的解决方案也在那里,登录后,向同一个 Django 服务器发出一个简单的 GET 请求,它将确保它返回的 cookie 包含新更新的 csrftoken。这与您如何第一次向 Django BE API 发出 POST 请求的逻辑相同,简单,事先发出 GET 请求

由于 Angular 应用程序不是由 django 服务的,为了让 cookie 被设置,Angular 应用程序需要先向 django 发出 GET 请求。

方法仅在您CSRF_USE_SESSIONS设置为时才有效False,这意味着 Django 将 CSRF 令牌值设置为 cookie 的一部分

相关阅读:


推荐阅读