Session cookie not being created only in production - ruby-on-rails

I've been struggling with this for a while now and just can’t figure out why this is not working. I use Firefox/Firebug to see the session cookie being created in Development mode but when I run locally in Production the session cookie is not created. This, of course, causes all sorts of grief when the CSRF token is not in the session cookie and an exception is thrown.
The obvious place to look is in production.rb vs development.rb as all the rest of the code is the same however I can't see anything wrong there and I compared both files to a (test) newly created rails app.
Config Info:
session_store => cookie_store (rails default)
protect_from_forgery with: :exception (application_controller)
Any thoughts are appreciated. Thanks, Art

When I recently encountered the same situation, it turned out to be a problem with misconfigured session cookie domain.
Look into the HTTP headers your application sends with the responses. I guess the Set-Cookie header is sent for the session cookie as expected, but the browser refuses to save the cookie, because domain specified in the header doesn't match the actual production domain your application is running on.
To fix this, fix domain setting in the session store configuration.

Nope, neither of these were the problem. It was using Rack::Cached. I didn't have time to track down the why of it, just that removing it from my build stopped the problem without having to do anything else. Wish I'd had time to track this down further to help you all out.

Related

Rails/Heroku/Cloudflare: Can't verify CSRF token authenticity after domain change

We have a Rails 5.2.3 app in production using Devise 4.6.2 and being deployed at Heroku. The app was using a domain example.com and everything was fine. Today we needed to change that domain to app.example.com (example.com is now a WordPress site) and now when we try to log into the app we're getting:
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 19ms
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/request_forgery_protection.rb:211:in `handle_unverified_request'
One thing I've realized is that now our production app isn't setting the session cookie. Our staging app (which uses an example.herokuapp.com domain) sets a cookie named '_myapp_session' (and it's still working fine), while in our production app there's no cookie being set.
While googling about this I've found some mentions to the session_store.rb config (we didn't even had this file), so I created the file in config/initializers and tried to set to our app.example.com domain and also to domain: :all, but it didn't seem to make any difference.
Rails.application.config.session_store :cookie_store, key: '_app_myapp_session', domain: :all
What I am missing here? Why would the domain change stop the app from creating the session cookie?
Oh, and we're using Cloudflare as our DNS and its __cfduid cookie is being correctly set. Could that be related?
So, apparently it was indeed related to Cloudflare. Our app.example.com entry on Cloudflare's DNS was "proxied" and once I've set it to "DNS only" and waited a few minutes our session cookies started appearing again.
I've just now realized that Cloudflare has its own cache, so I've purged that and will try to use the "proxied" setting again, but if that doesn't work I'll just use it as DNS.
If someone has details on why Cloudflare's proxied setting would stop the cookies from being set, please let me know. Thanks!
Did you read this post about Cloudflare cached pages and CSRF?
Poor tl;dr: If you cache a page with a CSRF protected form you have to update de CSRF using Ajax.
https://blog.cloudflare.com/the-curious-case-of-caching-csrf-tokens/

Rails 4 upgrade throwing InvalidAuthenticityToken

My application just upgraded to Rails 4 and we're starting to see random InvalidAuthenticityToken errors. I have done a bunch of investigating but not yet found a solution. Anyone know what happened and how to fix it?
Calling out things that appeared in other similar SO questions but do not apply to me:
We call protect_from_forgery with: :exception in ApplicationController, but we were doing this in Rails 3 as well and did not have this error.
I have confirmed these are normal users using the website in a standard fashion; these are not CSRF attempts.
These are not API calls, they are standard web form submissions.
The authenticity token is present in both the form (via Rails form_for or form_tag generation) and in the submitted request.
My sessions should not have an expiration set, since I do not set an expiration time and the Rails default is forever, and my users don't often log in or out (so expired tokens are unlikely, as is "had a tab open, logged into a separate tab, went back to open tag and attempted action").
The csrf_meta_tag was generating the same tokens as my forms and removing it does not help.
My users confirmed they experienced this on at minimum Firefox, Chrome and Safari.
All code is available on Github.
Possibly relatedly: if I change my development secret_key_base in secrets.yml and change my session_store.rb file to use:
Rails.application.config.session_store :cookie_store, key: '_glowfic_constellation_' + Rails.env, domain: 'glowfic.com', tld_length: 2 and restart the server, I am logged out and can reliably experience this error 100% of the time when attempting to log in.
Edit calling out a couple more things:
I can't force clear all sessions because I use cookie stores, but I've already reset the secret_key_base and cookie name in production, which (hard to tell but I think) helped? But did not fix the issue.
The "possibly related" seems to be unrelated, and to have been related to the domain "glowfic.com" not supporting "localhost"; if I use the domain localhost instead, I can't reproduce locally.

SSL Requests on staging environments fail

Our mobile app recently stopped authenticating properly with our server on our staging and staging2 environments. Fortunately production is fine.
We're using force_ssl in our API's Session and Registration controllers. It was working fine before; not really sure what changed.
What seems to be happening is that our app submits a POST request to either create a new session or user. This request is over SSL, but we get a 301 Moved Permanently with a location identical to the initial request. I believe this redirect is performed via GET and since no routes match a GET to that URL, we then get a 404 Not Found.
I can't figure out why this changed recently and why it's not affecting production.
Turns out it was something having to do with Engine Yard, and an upgrade of our environment solved the problem.

Rails - Session not saving

I have a session that is set but it does not appear to carry over to other pages. I'm on Rails 2.3.5 and Ruby 1.8.7. Has anyone else experienced this issue?
I've had this issue in Rails 3.1 when CSRF verification fails. This can happen if you use a tag manually rather than generate it via one of the built-in methods provided by Rails.
Search your log file for "csrf" (case insensitive search). If you see a log entry showing a csrf failure, it's likely Rails is resetting your session.
You may be losing your session between requests which can happen if it's not established properly in the first place. If you examine your cookies you may see the session identifier changing, being re-assigned, because of a validation failure.
It's also possible that it's being assigned to a domain that the browser subsequently rejects. This happens if an application is configured to use a specific domain, and is then re-hosted under a different one, even localhost.
You might have not used csrf meta tag in your layout. Try removing ' protect from forgery ' in application_controller.rb in controllers folder. Then try running the app again, if it works then you didn't add tags to your layout.

are cookies mandatory for Ruby on Rails app?

is it true that Rails depend on cookies? It seems that flash is a part
of session, and session uses cookies... so when i disable cookie in
Firefox, a Rails app that was working shows
[error]
ActionController::InvalidAuthenticityToken
so is it true that for a RoR app to work, cookies are mandatory?
Update: or, to make the Rails app work again, what is the simplest way? (and if it is one server only (Apache running mod_rails), then is it easier?)
They are not mandatory, but there are some things you can't do without cookies. You can turn the authenticity tokens off as described here.
It's not mandatory to use cookies, but it is the rails default from 2.x up. Using cookies serves as a simple solution to some more difficult problems that arise when you try to store cookies in memory on multiple servers (and you get into things like sticky sessions, losing user data etc).
You can set where rails stores your session data; that is the flash and anything that's associated with the specific user. In environment.rb you can configure where you store your sessions using the config.action_controller.session_store. The options for this are: :cookie_store, :active_record_store, :p_store, :drb_store, :mem_cache_store, or :memory_store.
cookie_store is the default, if you comment the option out or remove it from environemnt.rb. It's also the most versatile. If you have multiple servers, one request for a user might come into one server, and the next request might come into a different server. In this situation, you couldn't use memory_store, as the 2nd server wouldn't know anything about the current user.
By storing session information in an encrypted cookie, there is less load on the server to store this information. The only downside is that each request to the server needs to pass the cookie (usually <1k), but it's not a noticeable difference in anything I've ever experienced.
:cookie_store, :mem_cache_store and :active_record_store are the most commonly used ones.

Resources