我有一个Django表单,我可以通过service worker离线使用。如果用户在脱机状态下完成表单,则要提交的数据将存储在IndexedDB中,然后注册一个background-sync;当浏览器重新联机时,将在服务工作器中激发sync事件,然后服务工作器可以从IndexedDB读取数据并通过fetch()将表单提交给后端。
但是,我打开了Django的CSRF保护。这要求我使用合法的CSRF令牌提交表单,该令牌存储在cookie中,但也存储在表单主体(或者更好的是X-CSRFToken头)以及fetch()请求的一部分中。不幸的是,因为这是在服务工作者中发生的,所以我无法读取cookie来获取CSRF令牌。有一个向allow service workers to read cookies提交的提案,但它没有完成,目前已暂停,因此不可用。
我想过使用从服务工作者到主页的postMessage来请求主页读取cookie并将其发回,但是后台同步可能会在没有主页可供postMessage到的时候运行。
可以存储CSRF令牌,它在服务工作者生成和缓存表单时是有效的,但我不知道CSRF令牌保持有效多长时间,也不知道Django对它做了什么验证。
有没有一个明智的方法来解决这个问题?显然,我不想禁用CSRF保护。
发布于 2019-09-04 15:41:38
默认情况下,Django CSRF令牌的有效期为一年:https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-CSRF_COOKIE_AGE。例如,Django执行referer验证,然后比较两个标记的等价性。
您可以存储CSRF令牌(如您所说,当表单被缓存时,或者在脱机时捕获表单提交时保存它),然后,如果稍后提交的表单未通过CSRF验证并返回错误页面,请确保错误页面中包含有效的CSRF令牌,这样后台/脱机脚本就可以读取并重新提交相同的数据,然后有望成功。
https://stackoverflow.com/questions/57779378
复制相似问题