Django+AngularJS部署HTTPS服务器后登录表单出现403 CSRF验证失败
解决Django + AngularJS HTTPS环境下的CSRF 403错误
看起来你遇到的核心问题是**CSRF_COOKIE_HTTPONLY = True的配置阻止了AngularJS获取CSRF令牌**,导致请求头里缺少X-CSRFToken字段,触发Django的CSRF验证失败。
为什么会这样?
当你设置CSRF_COOKIE_HTTPONLY = True时,浏览器会限制JavaScript读取这个Cookie——而你在AngularJS里配置的$httpProvider.defaults.xsrfCookieName = "csrftoken",正是依赖JS从Cookie中提取令牌并自动添加到请求头里。现在JS拿不到这个Cookie,请求自然就没有携带验证所需的令牌,返回403 Forbidden。
解决方案
这里有两种可行的方案,你可以根据安全需求选择:
方案1:关闭CSRF Cookie的HTTPONLY属性(最简单)
修改local_settings.py中的配置:
# 原来的配置 # CSRF_COOKIE_HTTPONLY = True # 修改为: CSRF_COOKIE_HTTPONLY = False
这样AngularJS就能正常从Cookie中读取csrftoken,并自动将X-CSRFToken头添加到请求中,Django的CSRF验证就能通过。
方案2:保留HTTPONLY(更安全),手动从页面获取令牌
如果你想保持CSRF_COOKIE_HTTPONLY = True(这个配置能降低XSS攻击窃取CSRF令牌的风险),可以在页面中渲染令牌,让AngularJS从DOM元素中读取:
- 在
login_register.html中添加Django的CSRF令牌标签:
<div ng-app="app" ng-controller="Ctrl"> {% csrf_token %} <!-- 新增这一行 --> <form method="post" name="loginForm" ng-submit="login()"> <!-- 原有表单内容不变 --> </form> </div>
这会生成一个隐藏的<input>元素,包含当前的CSRF令牌。
- 修改
login-register.js,手动获取令牌并添加到请求头:
var app= angular.module("app",[]); app.config(function($interpolateProvider, $httpProvider){ $interpolateProvider.startSymbol("[[["); $interpolateProvider.endSymbol("]]]"); // 可以保留原来的xsrf配置,但我们手动设置头会覆盖它 }); app.controller("Ctrl", function($scope, $http, $window){ $scope.loginError= ''; // 从页面隐藏元素中获取CSRF令牌 const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value; $scope.login= function(){ $scope.submittingForm= true; $scope.loginError= ''; var formData= { "username": $scope.login.email, "password": $scope.login.pw }; $http.post( "login", JSON.stringify(formData), { headers: { 'X-CSRFToken': csrfToken, 'Content-Type': 'application/json' } } ).success(function(response){ if (response.success === false){ $scope.loginError= response.err_msg; $scope.submittingForm=false; return; } $window.location.href= GLOBAL_paths.home; }); }; });
额外检查点
为了确保万无一失,你可以在浏览器开发者工具里做以下验证:
- 查看
Application标签下的Cookies,确认csrftoken存在,并且Secure属性为true(符合你CSRF_COOKIE_SECURE = True的配置)。 - 查看登录请求的
Network详情,确认Request Headers里包含X-CSRFToken,且值与Cookie中的csrftoken一致。
内容的提问来源于stack exchange,提问作者Username
相关产品推荐
相关产品推荐

