后端和前端分离时的Django CSRF

Posted

技术标签:

【中文标题】后端和前端分离时的Django CSRF【英文标题】:Django CSRF when backend and frontend are separated 【发布时间】:2011-12-26 00:02:36 【问题描述】:

在网上搜索后,人们通常会处理这种情况---前端是由django view函数生成的,它可以向用户发送csrf token的cookie。当用户使用 ajax 向服务器发出请求时,人们可以重写将 csrf 发送到服务器的 ajaxSend 行为。

但是,我的情况是我的前端与后端完全分离,即我的前端在一个运行 nginx 的专用服务器中,我只有一个 html 使用 hashbang 提供所有不同的页面。我的后端运行在不同的服务器上,使用不同的域名,在这种情况下,客户端如何获取 csrf cookie?我的后端只提供了 json api 返回。

谢谢。

【问题讨论】:

请回答某人这个=/ 【参考方案1】:

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. 您只需要将 post 值返回到您的服务器,因为 cookie 应该已经通过 ajax 设置。 If you look at the template tag source you can see that it is just taking the variable out of the context. 要么将其从上下文中拉出(如果可用)将其粘贴到您的响应中,要么 calling the context processor directly. 现在您只需将其作为 POST 变量 crsf_token 发送回。

【讨论】:

【参考方案2】:

假设前端有域 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

【讨论】:

【参考方案3】:

这篇文章已经很老了,但对于仍然在这里徘徊的人来说: 对于客户端-服务器设置,例如本地桌面和移动客户端(以及像 OP 那样的单独前端),最好使用 Django Rest Framework 的令牌身份验证。 Link

【讨论】:

我不是安全专家,但据我所知,这是使用完全解耦的前端和后端来防止 CSRF 攻击的唯一真正方法。否则,您将不得不公开一个端点以从您的后端生成一个 CSRF 令牌,这与使用 CSRF 令牌的意义相悖。

以上是关于后端和前端分离时的Django CSRF的主要内容,如果未能解决你的问题,请参考以下文章

前后端分离,解决跨域问题及django的csrf跨站请求保护

nodeJS(前后端分离、优势、不足

在同一个域上分离后端和前端应用程序?

如何使用分离的后端和前端(Passport / Express / React)进行社交身份验证

vue你真棒

django前后端分离与不分离概念