后端和前端分离时的 Django CSRF
在网上搜索后,人们通常会处理这种情况——前端是由django视图函数生成的,它可以向用户发送csrf token的cookie。当用户使用ajax向服务器发出请求时,人们可以重写ajaxSend行为,将csrf发送到服务器。
然而,我的情况是我的前端与后端完全分离,即我的前端位于运行 nginx 的专用服务器中,并且我只有一个 html 使用 hashbang 提供所有不同的页面。我的后端使用不同的域名运行在不同的服务器上,在这种情况下,客户端如何获取csrf cookie?我的后端只提供json api返回。
谢谢。
After searching the internet, people normally deal with this situation---the front-end is generated by django view function which can send user the cookie of csrf token. When user has a request to server using ajax, people can rewrite the ajaxSend behavior which send the csrf to server.
However, my situation is that my front-end is totally separated from back-end, ie, my front-end is in a dedicated server running nginx, and I only have one html providing all of the different pages using hashbang. My back-end is running in different server using different domain name, and in this case, how does client obtain the csrf cookie? My back-end only provided json api return.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这篇文章已经很老了,但对于仍然在这里徘徊的人来说:
对于客户端-服务器设置,例如本机桌面和移动客户端(以及像 OP 的情况一样的单独前端),最好使用 Django Rest Framework 的令牌身份验证。 链接
This post is quite old but for people who still wander here:
For client-server setups, such as native desktop and mobile clients (and separate front end like the OP's case), it is best to use Django Rest Framework's Token Authentication. Link
如果您查看 CRSF 令牌源:您可以看到所有csrf_middleware 会根据 post 值检查 cookie。 您只需要将 post 值返回到您的服务器,因为 cookie 应该已经通过 ajax 设置了。 如果您查看模板标签源,您可以看到它是只需将变量从上下文中取出即可。 要么将其从上下文中拉出(如果可用),要么将其粘贴在您的响应中,或者直接调用上下文处理器。现在你只需发送它作为 POST 变量 crsf_token 返回。
If you look at the CRSF token source: you can see that all the csrf_middleware does it check the cookie against the post value. You just need to get the post value back to your server since the cookie should of already been set though ajax. If you look at the template tag source you can see that it is just taking the variable out of the context. Either stick it in your response by pulling it out of the context if it is available or calling the context processor directly. Now you just need to send it back as the POST variable crsf_token.
比方说,前端的域为 frontend.example.com,后端的域为 backend.example.com。 (如果你是类似Django Rest框架的东西)
如果可以使用,有两种方法可以启用安全层,即。 CSRF 保护或 CORS
对于 CORS,
然后将其配置为 INSTALLED_APPS、MIDDLEWARE_CLASSES 并将前端域添加到 CORS_ORIGIN_WHITELIST。
CORS 将阻止来自 frontend.example.com 以外的任何域的任何 http 请求
对于 CSRF,
如果您使用的是 Angular 应用程序,请执行如下操作,
然后在发出 http 请求时添加标头。
Lets say, frontend has the domain frontend.example.com, and backend domain backend.example.com. (If you are something like Django rest framework)
If you can use there are two ways you can enable security layer i.e.,. CSRF Protection or CORS
For CORS,
and then configuring this to INSTALLED_APPS, MIDDLEWARE_CLASSES and add the frontend domain to CORS_ORIGIN_WHITELIST.
CORS will block any http request arising from any domains other than frontend.example.com
For CSRF,
and if you are using an Angular App, do like below,
and then add headers while make a http request.