我使用mod_wsgi在apache服务器上运行django,以及直接由apache服务的angularjs应用程序,而不是django . 我想对django服务器进行POST调用(运行rest_framework),但我遇到了csrf令牌的问题 .
有没有办法从服务器设置令牌而不将 {% csrf token %}
作为模板的一部分(因为这些页面不通过django)?
-
我希望能够通过GET请求获取csrf令牌作为cookie .
-
我希望能够使用csrf令牌cookie值向django服务器发出POST请求 .
5 回答
Django和AngularJS都已经拥有CSRF支持,你的部分非常简单 .
首先,您需要在Django中启用CSRF,我相信您已经这样做了,如果没有,请关注Django doc https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax .
现在,Django将在第一个GET请求中设置一个名为
csrftoken
的cookie,并期望在以后的POST / PUT / DELETE请求中使用自定义HTTP头X-CSRFToken
.对于Angular,它期望名为
XSRF-TOKEN
的cookie并且将使用X-XSRF-TOKEN
标头执行POST / PUT / DELETE请求,因此您需要进行一些调整以使两者相互依赖:在你的js代码中的某处添加以上两行,module.config()块是一个很好的地方 .
而已 .
NOTE: 这是针对角度1.1.5,旧版本可能需要不同的方法 .
更新:
由于角度应用程序不是由django提供的,为了让cookie设置,角度应用程序需要首先对django执行GET请求 .
所有使用$ http的模块服务和控制器都将使用csrf令牌发送请求 .
搜索后,对我有用的是this post,代码如下:
这当然是在通过django服务器的GET请求获取cookie之后 .
我也在这里查看了其他一些答案,包括Ye Liun 's but couldn' t在官方文档中找到任何指定$ httpProvider上xsrf的默认选项的更改,而不是this pull request,这在我写作时对我不起作用这个帖子 .
我为我的AngularJS应用程序创建了一个Django应用程序,与我的(REST)API Django App在同一个Django项目中,它只提供index.html文件(它只是一个sym.link) . 通过这种方式,CSRF Cookie无需额外的GET请求即可设置 .
请在这里查看我的回答AngularJS Single Page Web Application on Sub-domain A talking to a Django JSON (REST) API on Sub-domain B using CORS and CSRF protection
如果您将Cookie设置为禁止javascript访问,则需要执行以下操作 . 在模板中,在创建django应用程序之前,添加以下内容:
在您的角度应用中,添加以下内容:
至少通过Django 1.9,CSRF令牌不会随着每个请求而改变 . 它仅在用户登录时更改 . 如果您正在执行单页角度应用程序,则需要确保在登录/注销时重置令牌,这应该可以正常工作 .
注意:由于每个请求上的CSRF令牌发生变化,因此目前在Django 1.10或更高版本中不起作用 . 见Pass Django CSRF token to Angular with CSRF_COOKIE_HTTPONLY