我正在为 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,而且超出了他的能力范围。为菜鸟问题道歉(如果是的话)。
首先你必须获得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 请求的所有标头中。