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

如何从Django获取初始CSRF Token供Angular前端登录使用?

Django + Angular CSRF Token 标准实现方案

一、Django 端核心配置

1. 确认CSRF中间件存在

在settings.py的MIDDLEWARE列表中,确保django.middleware.csrf.CsrfViewMiddleware处于正确位置:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 必须在SessionMiddleware之后,AuthMiddleware之前
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

2. 给登录相关视图添加@ensure_csrf_cookie装饰器

这个装饰器会强制Django在响应中设置CSRF Token cookie,无论视图是否被CSRF保护。

函数视图示例:

from django.views.decorators.csrf import ensure_csrf_cookie
from django.shortcuts import render

@ensure_csrf_cookie
def login_page(request):
    return render(request, 'login.html')

类视图示例:

from django.views.decorators.csrf import ensure_csrf_cookie
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView

@method_decorator(ensure_csrf_cookie, name='dispatch')
class LoginPageView(TemplateView):
    template_name = 'login.html'

DRF API登录视图示例:

如果用Django REST Framework写登录接口,同样需要给视图添加装饰器:

from rest_framework.views import APIView
from rest_framework.response import Response
from django.views.decorators.csrf import ensure_csrf_cookie
from django.utils.decorators import method_decorator

@method_decorator(ensure_csrf_cookie, name='dispatch')
class LoginAPIView(APIView):
    def post(self, request):
        # 处理用户名密码验证、登录逻辑
        return Response({'status': 'success'})

二、Angular 端自动处理CSRF Token

Angular内置了HttpClientXsrfModule,可以自动读取CSRF cookie并添加到请求头中,无需手动处理。

1. 在AppModule中配置

import { NgModule } from '@angular/core';
import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http';

@NgModule({
  declarations: [/* 组件声明 */],
  imports: [
    HttpClientModule,
    // 配置Django对应的cookie和请求头名称
    HttpClientXsrfModule.withOptions({
      cookieName: 'csrftoken', // Django默认的CSRF cookie名
      headerName: 'X-CSRFToken' // Django默认的CSRF请求头名
    })
  ],
  providers: [],
  bootstrap: [/* 根组件 */]
})
export class AppModule { }

2. 发送登录请求

使用Angular的HttpClient发送POST请求时,会自动携带CSRF Token:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

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

  login(username: string, password: string) {
    // 跨域场景需添加withCredentials: true
    return this.http.post('/api/login/', { username, password }, { withCredentials: true });
  }
}

三、排查常见问题

  1. 未生成CSRF Cookie:检查浏览器开发者工具的Network面板,查看登录页面/接口的响应头是否有Set-Cookie: csrftoken=xxx。如果没有,确认:

    • 中间件CsrfViewMiddleware已配置且顺序正确
    • 目标视图已添加@ensure_csrf_cookie装饰器
    • 请求路径正确匹配到了该视图
  2. 请求未携带CSRF Token:查看登录请求的请求头是否包含X-CSRFToken字段。如果没有,确认:

    • Angular的HttpClientXsrfModule配置正确
    • 跨域场景下请求添加了withCredentials: true
    • 浏览器允许第三方cookie(如果是跨域)
  3. 跨域场景额外配置:如果前后端域名不同,需在Django中配置CORS:

    • 安装django-cors-headers并添加到INSTALLED_APPS和MIDDLEWARE
    • 在settings.py中设置:
      CORS_ALLOW_CREDENTIALS = True
      CORS_ALLOWED_ORIGINS = [
          "http://localhost:4200", # Angular开发服务器地址
          # 其他允许的域名
      ]
      

内容的提问来源于stack exchange,提问作者bp-pet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:07:24