使用 fetch API 发送 POST 请求时处理 csrf 安全

问题描述 投票:0回答:1

我正在为 Django/Python Web 应用程序实现 Web 通知。

需求之一是记录目标用户“收到通知”的行为。

为了记录此指标,我使用 fetch API,如下所示:

function log_notif_reception(status_code) {

  fetch('/1-on-1/push-notif/received/', {
    "method": 'POST',
    "headers": {
      'Accept': 'application/json',
      'Content-Type':'application/json'
    },
    "credentials": 'include',
    "body": JSON.stringify({'status_code':status_code})

  })
  .then(function(response) {
    if (!response.ok) {
      throw new Error('Bad status code from server.');
    }
  });

}

这很简单。

问题在于,位于此 POST 请求接收端的服务器端的

view
需要
csrf token
以确保这不是
Cross-Site Request Forgery
攻击。

但是,在这个场景中没有

document
对象可以从中提取 csrf 令牌。收到通知的用户可能不会打开 Web 应用程序。因此,我无法运行如下所示的内容:

function get_cookie(name) {
  if (!name) { return null; }
  var value = "; " + document.cookie;
  var parts = value.split("; " + name + "=");
  if (parts.length >= 2) return parts.pop().split(";").shift();
}

为了避免这个问题,我必须制作服务器端视图

csrf_exempt
。我觉得这样不太安全。

所以我想请教专家,他们将如何处理这样的场景的安全方面?

顺便说一句,这里的服务器端开发人员不得不涉足 JS,而且超出了他的能力范围。为菜鸟问题道歉(如果是的话)。

javascript service-worker web-notifications
1个回答
0
投票

首先你必须获得csrf。 假设您使用不同的域来托管前端和后端。 确保您安装了 cors 并进行了设置(设置在网站中)。

你必须访问django中的settings.py并添加以下内容

CORS_ORIGIN_WHITELIST = ['http://localhost:3000']
CORS_ALLOW_CREDENTIALS = True
CSRF_TRUSTED_ORIGINS = ['http://localhost:3000']

之后,您可以从 django 中的专用视图获取 csrf。所以在你看来.py

from django.middleware.csrf import get_token

def gettoken(request):
return JsonResponse({'crsftoken': get_token(request)})

然后添加 url 路径。在 urls.py 中 路径('/gettoken',views.py,名称='gettoken')

这样您就完成了服务器端的工作。之后,您从前端执行一个 api,它会返回一个 csrftoken,然后您必须将其包含在发送需要 csrf 的 post 请求的所有标头中。

© www.soinside.com 2019 - 2024. All rights reserved.