Angular 6集成Django CSRF:登录后如何重置CSRF Token?
解决Angular 6与Django集成时登录后CSRF Token失效的问题
我之前也踩过这个坑!Django在用户登录时确实会刷新CSRF Token,而Angular默认的CookieXSRFStrategy只会在应用初始化时读取一次Cookie里的Token,这就导致登录后发送的POST请求带着旧Token,被Django拒绝。下面给你两个靠谱的解决办法:
方法一:登录成功后手动更新CSRF Token
这个思路是在登录请求成功后,主动读取Django返回的新CSRF Cookie,然后更新Angular请求头里的Token值。
步骤:
- 先安装
ngx-cookie-service来方便读取Cookie:
npm install ngx-cookie-service --save
- 在你的
AuthService里修改登录逻辑,登录成功后更新Token:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { CookieService } from 'ngx-cookie-service'; @Injectable({ providedIn: 'root' }) export class AuthService { constructor( private http: HttpClient, private cookieService: CookieService ) {} login(username: string, password: string) { return this.http.post('/api/login/', { username, password }).subscribe( (res) => { // 登录成功后,读取Django刚设置的新csrftoken const newCsrfToken = this.cookieService.get('csrftoken'); // 更新全局请求头的CSRF Token this.http.defaults.headers.common['X-CSRFToken'] = newCsrfToken; // 这里也可以把Token存到其他地方,比如服务变量里供后续请求用 }, (err) => { // 处理登录错误 } ); } }
- 别忘了在
AppModule里导入CookieService:
import { CookieService } from 'ngx-cookie-service'; @NgModule({ // ...其他配置 providers: [ CookieService, // ...其他服务 ] })
方法二:自定义XSRF策略,每次请求都读取最新Cookie
这个方法更彻底,自定义一个XSRF策略类,让它每次发送请求前都重新读取Cookie里的最新Token,从根源上避免Token过期的问题。
步骤:
- 创建自定义策略类
CustomXSRFStrategy:
import { Injectable } from '@angular/core'; import { XSRFStrategy } from '@angular/http'; import { CookieService } from 'ngx-cookie-service'; @Injectable() export class CustomXSRFStrategy implements XSRFStrategy { constructor(private cookieService: CookieService) {} configureRequest(req: any): void { // 每次请求前都读取最新的csrftoken const token = this.cookieService.get('csrftoken'); if (token) { req.headers.set('X-CSRFToken', token); } } }
- 在
AppModule里替换默认的XSRF策略:
import { CookieService } from 'ngx-cookie-service'; import { CustomXSRFStrategy } from './custom-xsrf.strategy'; @NgModule({ // ...其他配置 imports: [ // 建议你统一用HttpClientModule,HttpModule已经被废弃了 HttpClientModule, // HttpModule, 可以删掉这个 ], providers: [ CookieService, { provide: XSRFStrategy, useClass: CustomXSRFStrategy } ] }) export class AppModule {}
额外提醒
- 确保Django的CSRF配置是默认的(
CSRF_COOKIE_NAME = 'csrftoken'),这样Angular才能正确读取到Cookie。 - 你当前代码里同时导入了
HttpModule和HttpClientModule,Angular 6推荐使用HttpClientModule,HttpModule已经被标记为废弃,建议统一替换成HttpClient相关的API。
内容的提问来源于stack exchange,提问作者Marcus Grass
相关产品推荐
相关产品推荐

