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.
Related
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.
I know what CSRF protection is, I know how it works in the context of a Rails app, and I know how to "solve" my problem, e.g., by disabling it.
However, I'd like to keep CSRF protection turned on. My question is, what would cause the error:
Can't verify CSRF token authenticity
To appear overnight? Nothing has been pushed to production (i.e., not a code issue, and FYI I'm not using Devise). Still using the same browser (Chrome on desktop) which has not been updated. Using the same form (a template that every user uses). Literally yesterday it was all working fine, and today it suddenly isn't.
Only guessing possible here I guess.
Precondition: There is no bug ;-) Guess: A real CSRF attack is going on.
Precondition: Not yet checked twice. Guess: Something had been modified on production. Maybe it was not even pushed, but directly changed.
Precondition: Production site is not heavily used. Guess: It was broken since longer than the night before. Nobody noticed, since all they did was logging in and triggering some 'GET' requests, and not the template form.
"csrf-token" or "csrf_token"? Sometimes GET and POST requests modify the variable name. Especially if you disable Javascript and the original post becomes a get. Of course that would be a different route, but still might throw the csrf error.
I'm in the process of upgrading a Rails app from Rails 2 directly to Rails 4. I'm using the new /config/initializers/session_store.rb file, with CookieStore, but for some reason my sessions are not saving.
When trying to do something along the lines of
render :text => "#{request.session_options[:id]}"
I get a new session ID every refresh.
I've tried on different browsers, and all should be accepting cookies.
I have no idea what's going on. Why won't these sessions persist?!
Edit: thank you all for your suggestions. Here's a little more information, and a few things I've noticed:
First, about my set up -- I'm running the server with Rails 4/Ruby 2 through RVM on an Ubuntu VM on my Windows 7 machine.
Although I'm upgrading from Rails 2, that only really applies to the models/controllers/views/etc -- I generated a new Rails 4 application for all of the supporting infrastructure.
I created another application on the same VM that JUST sets a session and then displays, and that works fine.
What the session is storing varies slightly depending on what the user is doing, but usually it holds simply a user id (just an integer), and occasionally a little more -- (i first noticed this manifesting itself while trying to pass an OAuth token from the OAuth gem.)
I've noticed that if the VM's system clock falls behind the Windows 7 host machine clock, the user id sessions hold. That causes other problems, especially with OAuth, but there seems to just be a time issue somewhere. I've tried doing things like removing the time zone from my environments/development.rb, but that did not help.
As a general answer a couple of possible problems are
Session size over 4K limit (which is apparently the case).
CookieOverflow is raised if you attempt to store more than 4K of data.
Please, bear in mind that if you store an object in session, the object is previously serialized before storing it and its size would be bigger. More info on the general problem and possible solutions for the specific problem, here.
Problems with CSRF protection.
If the security token doesn't match what was expected, the session
will be reset
Edit: To check if it is a CSRF case, you can, as Abdo comments below, temporarily disable the protect_from_forgery line in ApplicationController
I had a similar symptoms. It turns out it was because I added the rails-api gem and it totally broke session saving.
From: Railscasts Episode 415 Upgrading to Rails 4
There’s one more configuration change we need to make, in the secret
token initializer. In Rails 4 the configuration option in this file
has been renamed from secret_token to secret_key_base. We’ll need to
specify both options while we’re transitioning from Rails 3 but once
we’ve successfully migrated our application we can remove the
secret_token option. It’s best to use a different token for our
secret_key_base.
This is necessary because we’re moving from a serialized cookie stored
on the client to an encrypted cookie. This prevents users from easily
being able to see the contents of their session cookies.
The episode includes a very good series of tips regarding upgrading from 2 to 4 and I was able to do that successfully using this tutorial.
I've got a Rails 2.3.5 application that I'm migrating to Rails 3.0.10 that's run into a problem with sessions.
Some code is failing during integration tests because the session has no id (request.session is an empty hash, and request.session_options[:id] is nil). We are currently using webrat, but the same thing happens with capybara and with standard rails helpers. Sessions do seem to be set up properly, since some of the integration tests have session ids. It looks like the session id is missing only in tests that don't log in before trying to access the session id (i.e. most of them).
I've tried switching the session backend (it's currently cookie based) to ActiveRecord, but that didn't help. I've created a new Rails 3.0.10 app, and it also has nil session ids. I've even dug into Rails's session handling, and it looks like there's no session id being generated on if a session is missing one.
Is this lack of session ids expected behavior that's documented somewhere? If it's a bug, is there a version of Rails that generates session ids properly?
The only way I've seen how to solve this is to prime the sessions.
sid1 = session[:session_id]
sid2 = request.session_options[:id]
However, if for some reason the session cookie is deleted, it can still happen.
I tried that and no result. I also tried session[:foo] = 'bar' as I liked the way it looked better but still no result.
I rebooted and still no joy. Then I went into my browser settings and deleted my cookies. That fixed it. From this experience it appears a cookie can keep sessions from being forced. I had been changing class names and changing my database tables. Somehow I had corrupted my cookie.
Seems that Rails has by default stopped checking authentication_token for ajax requests. per code request.xhr? is not checked anymore. It was not ignored in rails 2.3.2 but since 2.3.8 is ignored. Wanted to know what is the reason for this change and what uis the way to turn it on.
You need now check the format of the request to know what your want really served. It's really better than to know if you request is or not in xhr. This trick was bad because can be not support by all Javascript script.