All threads / Caching static pages without CSRF token

Ask A Question


You’re not receiving notifications from this thread.

Caching static pages without CSRF token

Nicolas Brousse asked in Rails


I'm looking to use expires_in method in my actions who returns static content.
For this pages I would like to return a cache control header where public is true. Like this it allow an proxy cache to store the content.

My question is more about CSRF token meta tags. I'm looking to have the CSRF meta tags not printed out when I use cache control has public. I was first looking to play with protect_from_forgery options but still print the tags.

I finally saw into Rails code that csrf_meta_tags are only printed if protect_against_forgery? returns true. And that is linked to self.allow_forgery_protection.

So I do this code that works for me.

class ApplicationController < ActionController::Base

  def expires_in(seconds, options = {})
    self.allow_forgery_protection = false if options.fetch(:public, false)

But may be there is a better way to do it or may be I miss some Rails tools.

What do you think about?

CSRF tokens are generated for each user, which is why they should not be cached. The CSRF tokens are specific to each user and request so that you can determine whether or not it was the user taking this action or malicious code.

To solve this you have 3 options:

  1. Don't cache the form
  2. If you're fragment caching, use Javascript to include the CSRF token. See here:
  3. If you're doing full-page caching, use one of these mthods:

Hi Chris,

Thanks for your answer and sorry for the time I spent to send mine.

In my case I'm looking for caching a full-page. My website doesn't contain form for now. It's only static pages. It will have a blog and may be a contact page with a form in the futur.

It's why I was looking to have an cache control as public for main of the pages. I looked, but I plan to use nginx to cache pages. So I can't use ESI. I could use cookie or an endpoint.
But may be in my case, I could just no care about meta tags and cache them anyway. Until I don't use cache control public in page with form.

Hey Nicolas,

That's great then. If you don't have any forms or anything for now, just cache it all and don't care about it.

You can add Javascript and an endpoint for the CSRF token later on when you add the contact form in the footer which you'll probably want to submit with AJAX anyways. It'd make perfect sense to just add in a csrf endpoint to retrieve the token and submit it in that case.

That's one of the easier solutions for caching since you don't have too much dynamic content and that'll make your life a whole lot simpler. :)


I'll keep CSRF token for static pages then.

Thanks for your help!

Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 34,885+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2020 GoRails, LLC. All rights reserved.