Ask A Question

Notifications

You’re not receiving notifications from this thread.

Caching static pages without CSRF token

Nicolas Brousse asked in Rails

Hi,

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 = {})
    super
    self.allow_forgery_protection = false if options.fetch(:public, false)
  end
end

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

What do you think about?

Reply

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: https://coderwall.com/p/0sctaa/forms-csrf-authenticity-token-and-fragment-caching-in-rails
  3. If you're doing full-page caching, use one of these mthods: https://www.fastly.com/blog/caching-uncacheable-csrf-security
Reply

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 https://www.fastly.com/blog/caching-uncacheable-csrf-security, 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.

Reply

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. :)

Reply

Great!

I'll keep CSRF token for static pages then.

Thanks for your help!

Reply
Join the discussion
Create an account Log in

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

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

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