【问题标题】:How to reduce service worker cache size when caching requests with CSRF tokens如何在使用 CSRF 令牌缓存请求时减少服务工作者缓存大小
【发布时间】:2018-05-06 04:16:29
【问题描述】:

我有一个服务工作者正在缓存来自浏览器的请求,因此该页面可以脱机工作。但是,每次用户注销并重新登录时,都会生成一个新的 CSRF 令牌,并且所有先前缓存的数据都无用,因为请求包含 CSRF 令牌作为查询字符串的一部分。这需要重新缓存所有相同的数据,因此我们在缓存中留下了多个数据副本,由于不同的 CSRF 令牌,每个副本只是具有不同的请求 URL。

我先查询网络,然后在网络不可用时故障转移到缓存。

我应该如何处理与 CSRF 令牌相关的这些响应的缓存?在执行 cache.put() 和 cache.match() 函数之前,我应该手动从 event.request 值中删除 CSRF 令牌吗?这甚至允许吗?通过修改请求 URL,似乎仍然可以返回先前为该请求缓存的值,即使用户已注销并重新登录,这将是所需的行为。

另外,如何删除所有与当前 CSRF 令牌不匹配的缓存请求,而不从缓存中清除所有条目?

这是相关的 Service Worker 代码:

self.addEventListener('fetch', function(event) 
// 'fetch' event lister: if the network is UP, fetch the data across the network and cache the result.
// If network is unavailable, attempt to fetch from cache.
{
    // Send a response, first by trying the network, then by looking in cache.  If both fail, an error occurs.
    event.respondWith(
        // Try to fetch the request from the network:       
        fetch(event.request)
            // If successful, cache a clone of the response, then return it.
            .then(function(response)
            {
                var r = response.clone();

                caches.open('offline-cache')
                    .then(function(cache)
                    {
                        cache.put(event.request, r);
                    })
                    .catch(function(error)
                    {
                        console.log("Unable to cache item: ", error);
                    });

                return response;
            })
            // If network fails, try to pull the item from cache.
            .catch(function(error)
            {
                // Open the cache
                return caches.open('offline-cache')
                    // When cache is open, attempt to match with desired request
                    .then(function(cache)
                    {
                        // Try to match:
                        return cache.match(event.request)
                        // If successful, return the match.  Errors bubble up to the main event.
                            .then(function(response)
                            {
                                return response;
                            });
                    })
                    .catch(function(error)
                    {
                        console.log("Cached entry not found. Error.");
                    });
            })
    ); // END event.respondWith
});

【问题讨论】:

    标签: javascript caching csrf service-worker


    【解决方案1】:

    如果要缓存的资源对于所有请求/用户都是相同的,并且可以通过删除某些 URL 参数(或完全删除查询字符串)来识别,则您的代码可以生成缓存键 URL 并使用该字符串而不是 Request获取和缓存 API 方法的对象:

    // Returns URL string used for caching that excludes authentication-specific URL params, etc
    function getCacheKeyUrl(request) {
      // Strip query string from URL
      return request.url.replace(/\?.*/,'');
    }
    
    self.addEventListener('fetch', event => {
      const cacheKeyUrl = getCacheKeyUrl(event.request);
    
      ...
    });
    

    然后您可以在代码中使用fetch(cacheKeyUrl)cache.put(cacheKeyUrl, r)cache.match(cacheKeyUrl) 等。

    【讨论】:

    • 谢谢,这几乎是我最终使用的。我只是使用正则表达式从 request.url 中删除 CSRF 令牌,并将剩余的字符串用作缓存键。这消除了相同数据但不同令牌的重复缓存条目。
    猜你喜欢
    • 1970-01-01
    • 2016-05-18
    • 1970-01-01
    • 2012-04-05
    • 2020-08-30
    • 2018-10-02
    • 1970-01-01
    • 2016-10-15
    • 1970-01-01
    相关资源
    最近更新 更多