Session not working in Rails 4
UPDATE:
I figured I could change the session in other activities, however, if I ever established a session in the request POST
, it won't last. If I change the action from POST
to GET
, then the session will not be saved.
ORIGINAL QUESTION:
I have a Rails 4.2.0.rc3 application. When the user logs in, the session is assigned to this user ID. However, the session does not last when I run the method current_user
. I have secret_key_base
in the file secret.yml
. Here is my session mate.
module SessionsHelper
def sign_in(user)
session[:id] = user.id
puts "signing in" * 100
puts session[:id].inspect
end
def signed_in?
current_user.present?
end
def current_user
puts "checking session" * 100
puts session[:id].inspect
Avatar.find_by(id: session[:id])
end
end
In my log file, I can see what is installed session[:id]
. When another action is performed and the method is called current_user
, the value session[:id]
is zero. What's wrong and how can I fix it?
source to share
Hm caused by your update that this only happens on POST, I remember an incomplete couple of things.
-
Rails has CSRF protection, but by default only applies to POST and not GET
-
The Rails CSRF defense logic will silently use the new session instead of raising it in CSRF failure cases. (I think it was a bad default choice personally).
I wonder what's going on.
To find out, you want to tell your Rails application that it is indeed throwing a noise crash exception when CSRF fails, instead of silently using the new orphan session.
In yours, app/controllers/application_controller.rb
find the line protect_from_forgery
and change to protect_from_forgery with: :exception
to tell Rails to actually raise the CSRF crash rate. (Actually, it looks like Rails 4.x is now being built with a newer version of this line, but if you have an app that you upgrade from 3.x it wouldn't. Hooray for railsdiff to make it easier to examine changes in the rails new
generated code via rail versions).
If you get an exception in your test case, then knowing what the problem is, you can find a suitable solution: either receive a POST request with proper CSRF protection, or disable CSRF protection for this action. If this is an API type request, you may not need CSRF protection.
For more information on this kind of problem, see
Do your troubles sound?
source to share
Not sure if this is your problem, but I remembered this when I was looking at upgrading to 4.1 (form 4.0).
Here is the link and section of the doc. I think this only applies to 4.1 not 4.0
3.5 Cookie Serializer Applications built before Rails 4.1 use marshalls to serialize cookie values ββinto signed and encrypted cookie jars. If you want to use the new JSON format in your application, you can add an init file with the following Contents:
Rails.application.config.action_dispatch.cookies_serializer =: hybrid This would transparently migrate the existing serialized cookie marshal to the new JSON based format.
When using the: json or: hybrid serializer, you have to be careful, all Ruby objects can be serialized as JSON. For example, date and time objects will be serialized as strings, and hashes will have their own string keys.
class CookiesController <Define element set_cookie cookies.encrypted [: expiration_date] = Date.tomorrow # => Thu 20 Mar 2014 redirect_to action: 'read_cookie' end def read_cookie cookies.encrypted [: expiration_date] # => "2014-03 -20 "end end It is advisable to store only simple data (strings and numbers) in cookies. If you need to store complex objects, you will need to handle the conversion manually when reading values ββon subsequent requests.
If you are using cookie session storage this applies to session and flash hash.
source to share