Django + Angular 5开发环境下CSRF验证问题求助
解决Django + Angular 5前后端分离的CSRF验证问题
嘿,我来帮你搞定这个跨域CSRF的坑!先提个醒:千万别随便用@csrf_exempt,这会直接关闭Django的CSRF防护,给你的应用带来严重的安全风险,咱们用标准的安全方案来解决问题。
下面是一步步的配置指南,亲测有效:
1. Django后端配置
首先把后端的CSRF和跨域基础配置做好:
- 先确认
settings.py里的中间件列表中存在django.middleware.csrf.CsrfViewMiddleware(默认是有的,别不小心删掉了)。 - 安装并配置跨域中间件
django-cors-headers,这是处理跨域请求的必备工具:- 先安装:
pip install django-cors-headers - 在
INSTALLED_APPS里加入corsheaders - 在
MIDDLEWARE里把corsheaders.middleware.CorsMiddleware放在django.middleware.common.CommonMiddleware前面,顺序很重要! - 然后在
settings.py里添加这些跨域和CSRF的关键配置:# 允许Angular开发服务器的跨域请求 CORS_ALLOWED_ORIGINS = [ "http://localhost:4200", ] # 允许请求携带cookie(CSRF令牌存在cookie里) CORS_ALLOW_CREDENTIALS = True # 开发环境下关闭HTTPS-only的cookie限制,生产环境再打开 CSRF_COOKIE_SECURE = False # 允许前端通过JS读取CSRF cookie,默认是True会禁止JS读取 CSRF_COOKIE_HTTPONLY = False # 信任Angular的域名,允许它携带CSRF令牌请求 CSRF_TRUSTED_ORIGINS = [ "http://localhost:4200", ]
- 先安装:
- 可选:你可以写一个简单的视图来主动返回CSRF令牌,方便前端调试:
然后在from django.http import JsonResponse from django.middleware.csrf import get_token def get_csrf_token(request): # 获取当前请求的CSRF令牌 return JsonResponse({'csrfToken': get_token(request)})urls.py里配置路由:path('api/get-csrf-token/', get_csrf_token, name='get_csrf_token')
2. Angular 5前端配置
Angular本身就内置了CSRF防护的支持,只要正确配置就行:
- 在
app.module.ts里,导入HttpClientModule和HttpClientXsrfModule,并配置对应的cookie和请求头名称(要和Django的对应上):import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http'; @NgModule({ imports: [ HttpClientModule, HttpClientXsrfModule.withOptions({ cookieName: 'csrftoken', // Django默认的CSRF cookie名称 headerName: 'X-CSRFToken', // 发送请求时要带的请求头名称 }) ], // ...其他模块、组件配置 }) export class AppModule { } - 发送请求的时候,一定要用
HttpClient(Angular 5里Http已经被弃用了),并且开启withCredentials来携带cookie:
比如在你的API服务里写POST请求:import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; @Injectable() export class ApiService { constructor(private http: HttpClient) {} submitData(data: any) { return this.http.post('http://localhost:8000/api/your-endpoint/', data, { withCredentials: true // 必须开启这个,才能携带CSRF cookie }); } }
3. 踩坑小贴士
- 第一次请求的时候,Angular会自动从cookie里读取CSRF令牌,然后在后续的POST/PUT/DELETE请求中自动把令牌放到
X-CSRFToken请求头里,不用手动处理。 - 如果还是遇到验证失败,可以先手动调用
/api/get-csrf-token/接口获取令牌,然后在请求头里手动设置,但一般Angular的内置机制已经足够。 - 开发环境下,一定要确保Django和Angular的服务器地址、端口都配置正确,别写错域名或者端口。
内容的提问来源于stack exchange,提问作者Måns Thörnvik
相关产品推荐
相关产品推荐

