如何从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 }); } }
三、排查常见问题
未生成CSRF Cookie:检查浏览器开发者工具的
Network面板,查看登录页面/接口的响应头是否有Set-Cookie: csrftoken=xxx。如果没有,确认:- 中间件
CsrfViewMiddleware已配置且顺序正确 - 目标视图已添加
@ensure_csrf_cookie装饰器 - 请求路径正确匹配到了该视图
- 中间件
请求未携带CSRF Token:查看登录请求的请求头是否包含
X-CSRFToken字段。如果没有,确认:- Angular的
HttpClientXsrfModule配置正确 - 跨域场景下请求添加了
withCredentials: true - 浏览器允许第三方cookie(如果是跨域)
- Angular的
跨域场景额外配置:如果前后端域名不同,需在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
相关产品推荐
相关产品推荐

