后端和前端分离时的 Django CSRF

发布于 2024-12-14 09:52:10 字数 285 浏览 1 评论 0原文

在网上搜索后,人们通常会处理这种情况——前端是由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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

三月梨花 2024-12-21 09:52:10

这篇文章已经很老了,但对于仍然在这里徘徊的人来说:
对于客户端-服务器设置,例如本机桌面和移动客户端(以及像 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

牛↙奶布丁 2024-12-21 09:52:10

如果您查看 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.

|煩躁 2024-12-21 09:52:10

比方说,前端的域为 frontend.example.com,后端的域为 backend.example.com。 (如果你是类似Django Rest框架的东西)
如果可以使用,有两种方法可以启用安全层,即。 CSRF 保护或 CORS

对于 CORS,

pip install django-cors-headers

然后将其配置为 INSTALLED_APPS、MIDDLEWARE_CLASSES 并将前端域添加到 CORS_ORIGIN_WHITELIST。

CORS_ORIGIN_WHITELIST = (
    'frontend.example.com'
)

CORS 将阻止来自 frontend.example.com 以外的任何域的任何 http 请求


对于 CSRF,

CSRF_COOKIE_DOMAIN = ".mydomain.com"

如果您使用的是 Angular 应用程序,请执行如下操作,

$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.withCredentials = true;

然后在发出 http 请求时添加标头。

headers : {
    "x-csrftoken" : $cookies.csrftoken
}

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,

pip install django-cors-headers

and then configuring this to INSTALLED_APPS, MIDDLEWARE_CLASSES and add the frontend domain to CORS_ORIGIN_WHITELIST.

CORS_ORIGIN_WHITELIST = (
    'frontend.example.com'
)

CORS will block any http request arising from any domains other than frontend.example.com


For CSRF,

CSRF_COOKIE_DOMAIN = ".mydomain.com"

and if you are using an Angular App, do like below,

$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.withCredentials = true;

and then add headers while make a http request.

headers : {
    "x-csrftoken" : $cookies.csrftoken
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文