You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular17对接Django时get_token()与CSRF_COOKIE不匹配求助

Angular 17 + Django CSRF令牌不匹配问题解决方案

核心问题分析

你的配置和实现存在几个关键冲突,导致令牌不匹配:

  1. Django CSRF存储方式错误:CSRF_USE_SESSIONS = True将令牌存在Session中而非Cookie,Angular无法直接读取Session内容。
  2. Cookie权限限制:CSRF_COOKIE_HTTPONLY = True禁止前端JS读取Cookie,Angular无法获取令牌;CSRF_COOKIE_SECURE = True在HTTP环境下(localhost开发)不会设置Cookie。
  3. 自定义令牌获取方式错误:通过接口返回令牌的方式,无法保证与Django当前会话绑定的Cookie令牌一致。

解决方案步骤

1. 修正Django配置(settings.py)

调整CSRF和CORS相关配置,让令牌能被Angular正确获取并传递:

CSRF_TRUSTED_ORIGINS = [
    "http://localhost:4200",
]
# 保持与Angular默认匹配的Cookie名称
CSRF_COOKIE_NAME = 'XSRF-TOKEN'
# 关闭Session存储,改用Cookie存储CSRF令牌
CSRF_USE_SESSIONS = False
# 开发环境禁用Secure Cookie(HTTPS环境再开启)
CSRF_COOKIE_SECURE = False
# 允许前端JS读取CSRF Cookie,供Angular HttpClient使用
CSRF_COOKIE_HTTPONLY = False
CSRF_COOKIE_DOMAIN = 'localhost'
CSRF_COOKIE_PATH = '/'

# CORS配置保持现有正确项
CORS_ALLOWED_ORIGINS = [
    "http://localhost:4200",
]
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_METHODS = [
    'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT',
]
CORS_ALLOW_HEADERS = [
    'accept', 'accept-encoding', 'authorization', 'content-type',
    'dnt', 'origin', 'user-agent', 'x-csrftoken', 'X-XSRF-TOKEN',
    'x-requested-with',
]

2. 简化后端CSRF令牌接口

不需要自定义返回令牌的接口,改为触发Django自动设置CSRF Cookie:

from django.http import HttpResponse
from django.middleware.csrf import get_token

def obt_csrf_token(request):
    # 触发Django生成并设置CSRF Cookie
    get_token(request)
    return HttpResponse(status=204)

这个接口的作用是让Django在响应中写入XSRF-TOKEN Cookie,而非返回令牌内容。

3. 调整Angular端实现

删除自定义的CsrfService,利用Angular HttpClient的自动XSRF处理能力:

  • 在app.module.ts中配置HttpClientXsrfModule:
import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http';

@NgModule({
  declarations: [/* 你的组件 */],
  imports: [
    HttpClientModule,
    // 配置与Django匹配的Cookie和请求头名称
    HttpClientXsrfModule.withOptions({
      cookieName: 'XSRF-TOKEN',
      headerName: 'X-XSRF-TOKEN'
    })
  ],
  providers: [],
  bootstrap: [/* 根组件 */]
})
export class AppModule { }
  • 发送登录请求时,只需启用withCredentials以携带Cookie:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class AuthService {
  constructor(private http: HttpClient) {}

  login(credentials: { username: string; password: string }) {
    return this.http.post(
      'http://localhost:8000/procesar_iniciar_sesion/',
      credentials,
      { withCredentials: true } // 必须开启,携带Cookie到后端
    );
  }
}

4. 验证流程

  1. 重启Django和Angular服务。
  2. 打开浏览器开发者工具,进入Application > Cookies > localhost,确认存在XSRF-TOKEN。
  3. 点击登录按钮,查看Network面板中POST请求的请求头,确认包含X-XSRF-TOKEN,且值与Cookie中的令牌一致。
  4. 后端Django会自动验证该请求头,无需额外处理(确保全局启用了django.middleware.csrf.CsrfViewMiddleware中间件)。

关键注意事项

  • 生产环境部署时,需将CSRF_COOKIE_SECURE = True重新开启,确保仅在HTTPS环境下传输Cookie。
  • 所有跨域请求必须携带withCredentials: true,否则Cookie不会被传递到后端。
  • 不要手动生成或返回CSRF令牌,依赖Django和Angular的自动机制即可保证令牌一致性。

内容的提问来源于stack exchange,提问作者Lázaro Bertín

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:56:09