1

我有一个 Django 表单,可以通过服务人员离线使用。如果用户离线完成表单,提交的数据将存储在 IndexedDB 中,然后注册后台同步;当浏览器重新上线时,该sync事件在 service worker 中触发,然后它可以从 IndexedDB 读取数据并通过fetch().

但是,我打开了 Django 的 CSRF 保护。这要求我提交带有合法 CSRF 令牌的表单,该令牌存储在 cookie 中,而且还包含在表单的正文中(或者更好的是在X-CSRFToken标头中)以及fetch()请求的一部分。不幸的是,因为这发生在服务工作者中,我无法读取 cookie 来获取 CSRF 令牌。有一个建议允许服务人员读取 cookie,但它尚未完成并且当前已暂停,因此不可用。

我考虑过使用postMessage从服务人员到主页来要求该主页读取 cookie 并将其发送回,但后台同步可能会在没有主页的时候运行postMessage

可以存储在服务工作者生成和缓存表单时有效的 CSRF 令牌,但我不知道 CSRF 令牌的有效期有多长,或者 Django 对其进行了哪些验证。

有没有明智的方法来解决这个问题?显然我不想禁用 CSRF 保护。

4

1 回答 1

2

默认情况下,Django CSRF 令牌有效期为一年:https ://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-CSRF_COOKIE_AGE 。Django 执行例如referer 验证,然后比较两个令牌是否相等。

您可以存储 CSRF 令牌(当表单被缓存时,或者在离线时捕获表单提交时保存),然后,如果稍后提交该表单失败 CSRF 验证并返回错误页面,确保错误页面中包含有效的 CSRF 令牌,然后后台/离线脚本可以读取,并重新提交相同的数据,然后有望成功。

于 2019-09-04T07:41:37.857 回答