Angular resetting csrf token

2019-08-17 04:30发布

I'm using Angular 6 and having a hard time integrating Django's csrf with Angular's. I found in this thread that Django changes the token on login which, since I can both register and login using post requests with the same new session but not post anything after login seems to make sense.

The question becomes how I go about resetting the csrf token on login. The way the csrf is handled now in my Angular app is shown in the below code for my app module:

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 { }

So my question is, how do I get my app to reset the value on login? (Not necessarily specifically login, but how do I get that value to reset.)

1条回答
forever°为你锁心
2楼-- · 2019-08-17 05:17

Great question, this is a little tricky and my response is very much untested. However, since there was no single post/article I could find, I decided to put down what I make of this problem after reading multiple sources:

  • Django and Angular both understand CSRF by default; so you don't need to manually set an explicit CSRF header value when you make POST requests.
  • This is different from say jQuery where you have to find the CSRFToken from the cookie and then set the value it in the headers against the key "X-CSRFToken".
  • However, since Angular does not know the name of the keys, the name of the key to get the CSRF token from the cookie, and the name of the key to set in the Header, you need to configure the key names in Angular.
  • Once more: You are only setting the key names here, and not the values, because of #1, Angular does this automatically.

    Angular's HttpClient has built-in support for the client-side half of this technique. Read about it more in the HttpClient guide.

You can set the key names as follows in Angular 1:

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

The same can be achieved in Angular 2 and above as follows:

bootstrap(AngularApp, [
      HTTP_PROVIDERS,
      provide(XSRFStrategy, {useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')})
    ]);
  • Yes, you are right that upon login, the value of the CSRFToken changes, and you will need to GET it again, before you can make another POST request. And there-in lies your solution as well, after login, do a simple GET request to the same Django server, and it will ensure that the cookie it returns contains the newly updated csrftoken. This follows from the same logic as how do you make a POST request to a Django BE API the first time, simple, make a GET request beforehand

Since the angular app isn't served by django, in order to let the cookie to be set, angular app needs to do a GET request to django first.

This approach only works if you have CSRF_USE_SESSIONS set to False, meaning Django sets the CSRF Token value as part of the cookie

Related reading:

查看更多
登录 后发表回答