Drupal 9 workers to stop caching for logged in users

When I enable caching for my website on Page Rules I have a big problem. If the user was already logged he cannot log out and vise versa guests can’t log in, Cloudflare is trying really hard to cache everything and in other words, my website becomes static. But users have to log in and out, post something, etc.

Therefore I have two options:

  1. Change plan from free to $200 per month to bypass caching by cookies (not considering this).
  2. Create a worker to detect user cookies and bypass caching for them.

I found this article about creating workers for WordPress - cloudflare_workers [Joseph's Projects] - and changed it to fit Drupal. My version is the latest at the moment - 9.2.7.

The main difference is that Drupal’s logged-in user cookie starts with “SSESS…”.

So here is my code:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event))
})

async function handleRequest(event) {
  let request = event.request;
  let response = null;
  cookies = request.headers.get("Cookie");
  if (cookies && cookiesincludes("SSESS")){
    console.log("We have cookies. Don't cache.", cookies);
    response = await fetch(request);
    response = new Response(response.body, response);
    response.headers.set("x-cfw-cache", "BYPASS");
    return response;
  }
  let cache = caches.default;
  response = await cache.match(request);
  if (response && response.status !== 200){
    response = null;
  }
  if (!response){
    console.log("No cache. Will fetch.");
    response = await fetch(request);
    response = new Response(response.body, response);
    let responsecookies = response.headers.get("Set-Cookie");
    if (responsecookies && responsecookies.includes("SSESS")){
      //Drupal auth/test cookies are being set here. We don't want to cache.
      response.headers.set("x-cfw-cache", "NO");
    } else {
      
      response.headers.delete("Set-Cookie"); //Cloudflare won't cache responses containing Set-Cookie.
      response.headers.set("x-cfw-cache", "MISS");
      if (response.status == 200){
        event.waitUntil(cache.put(request, response.clone()));
      }
    }
  } else {
    response = new Response(response.body, response);
    response.headers.set("x-cfw-cache", "HIT");
  }
  
  return response
}

It deploys without errors, but when I assign this worker to route and open my website I see this error:

Error 1101

Worker threw exception

What happened?

You’ve requested a page on a website (site.com) that is on the Cloudflare network. An unknown error occurred while rendering the page.

What can I do?

If you are the owner of this website:
you should login to Cloudflare and check the error logs for site.com.

But I couldn’t find any error logs in my CF account.

Could please anyone help me with this?

Found error log. It’s located on the Workers’ main page. Here is the exception message:

...
"message": "cookiesincludes is not defined",
...

So I had an error in my code, instead of if (cookies && cookiesincludes("SSESS")) there shoud be if (cookies && cookies.includes("SSESS"))

Now my worker is not throwing errors. But there is no change in caching behavior.

My page rule:

site.com/
Browser Cache TTL: a day, Cache Level: Cache Everything, Edge Cache TTL: a day

Can’t edit the last post, there is *site.com/* obviously in my rule.

I’ve used Patrick Meenan’s code for this. It’s designed for WordPress, but has Cookies and Paths sections you can customize to bypass cache.

Thank you! It worked!

Just had to change top two constants:

// Cookie prefixes that cause a request to bypass the cache when present.
const BYPASS_COOKIE_PREFIXES = [
"SSESS",
];
// URL paths to bypass the cache (each pattern is a regex)
const BYPASS_URL_PATTERNS = [
/\/admin\/.*/
];
1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.