【问题标题】:Angular resetting csrf token角度重置 csrf 令牌
【发布时间】:2018-11-05 02:36:20
【问题描述】:

我正在使用 Angular 6,并且很难将 Django 的 csrf 与 Angular 的集成。 我发现in this thread 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 { }

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

【问题讨论】:

    标签: django angular post csrf


    【解决方案1】:

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

    • Django 和 Angular 默认都理解 CSRF;因此,当您发出 POST 请求时,不需要手动设置显式 CSRF 标头值
    • 这与说 jQuery 不同,您必须从 cookie 中 find CSRFToken,然后 set 在标题中针对键“X-CSRFToken”设置它的值.
    • 但是,由于Angular不知道key的名称,从cookie中获取CSRF token的key的名称,以及在Header中设置的key的名称,所以需要配置 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 包含newly updated csrftoken。这与第一次向 Django BE API 发出 POST 请求的逻辑相同,很简单,事先发出 GET 请求

    由于 django 不提供 Angular 应用程序,为了让 要设置的 cookie,角度应用程序需要向 django 发出 GET 请求 首先。

    如果您将 CSRF_USE_SESSIONS 设置为 False,则此 approach only works,这意味着 Django 将 CSRF 令牌值设置为 cookie 的一部分

    相关阅读:

    【讨论】:

    • 这是一个很好的回应,有很多信息,让我们看看我是否说对了。如果我在我的 settings.py 中添加CSRF_USE_SESSIONS = False 并在下一个帖子请求之前发出获取请求,cookie 应该自动更新吗?我的示例代码和您的 Angular 2 示例代码有什么区别吗?我正在使用 Angular 6。
    • 并不特别,我认为它们看起来一样。但是,我不是角度专家!
    • 遗憾的是没有成功,我开始认为我需要使用 TokenAuthentication 或其他东西。
    • 嗯,只是登录更改 csrf 令牌不起作用或您无法使其正常工作的特殊情况。
    • 我有一个better explanation here,我可以在注销时尽可能多地进行发布请求,但是当登录时,所有发布请求都返回 403 禁止,但获取请求很好。
    猜你喜欢
    • 2012-09-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 2016-02-27
    • 2021-11-23
    • 2014-05-17
    • 2011-09-24
    相关资源
    最近更新 更多