We are building a plugin for Rails to be used within iframe Facebook applications, and at one point we need to check if Rail's session id cookie as been set or not.
By default, this cookie is named _myprojectname_session, what we need to find out is the actual name of the cookie itself. So if it's not set, we can do some redirects to make sure the cookies are set.
How do we access the damn name of the cookie from anywhere? Or at least from within a controller?
Rails.application.config.session_options[:key]
I found the solution. In Rails 2.3.2 at least the session key in set in config/initializers/session_store.rb like this:
ActionController::Base.session = {
:key => '_myapp_session',
:secret => '[...]'
}
And you can read the value like this:
ActionController::Base.session_options[:key]
From Base.session to Base.session_options automagically, doesn't make much sense, and it caused me a big headache... lol
To access the name of the session cookie from within the view or the controller, you can say:
request.session_options[:session_key]
and then to access the raw value of that cookie, being an empty array if it's not set, you use:
request.cookies[ request.session_options[:session_key] ]
The cookie name ( aka session_key ) is set in your config/environment.rb file.
config.action_controller.session = {
:session_key => '_project_session',
:secret => 'long-secret-key'
}
In my experience, if there is an underscore in the key, IE SOMETIMES does not set the cookies. In other words, use 'projectsession' instead of '_project_session'.
I think that the session key is stored in a variable called ENV_SESSION_KEY
Note also this bug which affects tests around session_options in some versions of Rails 2.x: https://rails.lighthouseapp.com/projects/8994/tickets/2303-testrequest-doesnt-initialize-session_options
In Rails 3/4 I'm using this:
request.env["rack.request.cookie_hash"]
This is a hash that contains all the cookies for current user including the one for session.
The hash has as a key the name of the cookie, and as a value the value of the cookie
I couldn't work out how to do this in rails 3 :-(
Eventually I ended up putting this in config/initializers/session_store.rb
SESSION_KEY = '_myapp_session'
MyApp::Application.config.session_store :cookie_store, :key => SESSION_KEY
and then accessing this where needed, eg in a view...
<%= ::ENV_SESSION_KEY %>
Related
Im developing ruby on rails application. I want to get the persistent cookie value and session cookie value in the application. Can any please guide me on this
I have read that request.session_options[:id] will fetch the session_id, is that the one that is usually stored in session cookie? Please guide me if my way of understanding is wrong.Thanks in advance
In Rails, it is simple as calling the session or cookies hash.
# Set a simple session cookie
cookies[:user_name] = "david"
# Read a cookie
cookies[:user_name] # => "david"
# Delete a key
cookies.delete :user_name
The same goes for session.
So, the information that you are looking for is probably inside one of these two.
Take a look at the examples at http://www.tutorialspoint.com/ruby-on-rails/rails-session-cookies.htm
I am developing a simple shopping cart based on session_id i.e. for determination of a user cart items used session_id.
But when user closes a browser and then opens it again a session id is been changed. And he loses all his items in cart.
I suspect such feature I can provide with saving session id in cookie.
Am I right?
Any way my question is How to provide a functionality that allows users get their cart items even after closing a browser?
I recommend reading the Rails Guide: Action Controller Overview (http://guides.rubyonrails.org/action_controller_overview.html).
Sections 4 and 5 cover Sessions and Cookies and will give you a deeper understanding
on how to use them and will make it easier to tackle future challenges.
I would also check out the Ruby on Rails ActionDispatch::Cookies < Object Documentation
(http://api.rubyonrails.org/classes/ActionDispatch/Cookies.html)
An example of the controller code you are looking for is listed on this resource. Here is an example:
# Sets a cookie that expires in 1 hour.
cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now }
cookies[:your_cookie] = {
:value => "your_cookie_value",
:expires => 100.years.from_now
}
for more details, check it out.
Rails stores the session in a cookie by default. You can influence if
the cookie lives beyond a restart of the browser (see below).
Cookies ARE NOT shared between browsers. Ever.
If you want to use Opera to look at the shopping cart you just created in Firefox you need to authenticate to the shop in some way, for example with username and password.
See Rails 3 additional session configuration options (key, expires_after, secure) for a description of all the configuration options for your session.
you'll be wanting to look at :expire_after, for example
:expire_after => 24.hours
(Found here: Setting session timeout in Rails 3)
Wanted to know the meaning of the :secret and :key options while configuring the session_store. So, for example I have a config like the following:
MyApp::Application.config.session_store :active_record_store,
{:key => '_my_app_session', :secret => '5xb5x1g92e965b95b16e49x79gxx9999', :expire_after => 2.hours}
what would the :secret and :key options do here? I googled but not many answers.
Thanks
I'm pretty sure those options are only valid if you're using the cookie session store (rather than the active record session store). The key is the name of the cookie which contains the session data, and the secret is the value used to encrypt/decrypt the data stored in the cookie.
Active Record Session Store:
"The serializer may be one of marshal, json, or hybrid. marshal is the default and uses the built-in Marshal methods coupled with Base64 encoding. json does what it says on the tin, using the parse() and generate() methods of the JSON module. hybrid will read either type but write as JSON."
Adding: ActiveRecord::SessionStore::Session.serializer = :json to config/application.rb solved the issue for me.
I need to store a small piece of data (less than 10 characters) in a cookie in Rails and I need it to be secure. I don't want anybody being able to read that piece of data or injecting their own piece of data (as that would open up the app to many kinds of attacks). I think encrypting the contents of the cookie is the way to go (should I also sign it?). What is the best way to do it?
Right now I'm doing this, which looks secure, but many things looked secure to people that knew much more than I about security and then it was discovered it wasn't really secure.
I'm saving the secret in this way:
encryptor = ActiveSupport::MessageEncryptor.new(Example::Application.config.secret_token)
cookies[:secret] = {
:value => encryptor.encrypt(secret),
:domain => "example.com",
:secure => !(Rails.env.test? || Rails.env.development?)
}
and then I'm reading it like this:
encryptor = ActiveSupport::MessageEncryptor.new(Example::Application.config.secret_token)
secret = encryptor.decrypt(cookies[:secret])
Is that secure? Any better ways of doing it?
Update: I know about Rails' session and how it is secure, both by signing the cookie and by optionally storing the contents of the session server side and I do use the session for what it is for. But my question here is about storing a cookie, a piece of information I do not want in the session but I still need it to be secure.
Setting a secure cookie
cookies.signed[:secret] = {
:value => "foo bar",
:domain => "example.com",
:secure => !(Rails.env.test? || Rails.env.development?)
}
Accessing the cookie
cookies.signed[:secret] # returns "foo bar"
The cookie is signed using ActionController::Base.cookie_verifier_secret. You can set the cookie_verifier_secret in the initializer file.
As KandadaBoggu says, it looks like what you want is a session variable, and session variables are by default encrypted and stored in cookies. However, if you have a look at the contents of config/initializers/session_store.rb you will find something like the following:
# Be sure to restart your server when you modify this file.
MyRailsApp::Application.config.session_store :cookie_store, :key => '_my_rails_app_session'
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# MyRailsApp::Application.config.session_store :active_record_store
Which suggests to me that you should use the database for sessions instead of the cookie-based default, which shouldn't be used to store highly confidential information. The pre-cooked migration makes everything really easy to set up so there's very little overhead in doing so, and once it's done there's basically zero overhead if you need to add a new piece of secret information at a later date!
I'm re-posting JacobM's answer, that he deleted, because it was the correct answer and pointed me in the right direction. If he undeletes it, I'll delete this one and pick his as the best answer.
First of all, if you use encrypt_and_verify instead of encrypt it will
sign the cookie for you.
However, when it comes to security, I always prefer to rely on
solutions that have been vetted in public, rather than rolling my own.
An example would be the encrypted-cookies gem.
I have a rails app that has the following content in the config/initializers/session_store.rb file:
ActionController::Base.session = {
:key => '_app_session',
:secret => 'a really long string here',
:expire_after => 2.minutes
}
ActionController::Base.session_store = :active_record_store
So during normal operations we are seeing ActiveRecord objects created in the database for each session. The issue is that we don't always want to create a session for requests - we'd like to be able to turn off session creation for automated requests. We are seeing thousands of session records in the database, one for each automated request. Prior to rails 2.3.3, the following was possible:
class ApplicationController < ActionController::Base
session :off
...
end
but now in rails 2.3.3 "session :off" has been deprecated because sessions are now lazy-loaded - if you don't use them, they are not created. The problem seems to be that the session object is always assigned in the sessionstore.rb file, and therefore always created. If I remove the session assignment block from the config file, then no session records appear after an automated request. My question is, how can I move the configuration assignments to the session hash out of session_store.rb and into the ApplicationController class (or elsewhere) where the session can be conditionally assigned only if a request is not automated? I'm concerned that the session config data may be needed before the controller handler is executed. Where would I put the assignment of the session key values?
Thanks in advance for any help.
The config/initializers are one-time configurations, they usually only ran once, on startup. According to the documentation, the lazy loading will only initialize the session if the "session" object is touched during a request.
Are you certain that you don't touch the session variable at all in your request cycle? (That is, in the filters, actions, helpers or templates). Also, do the session objects have some content that could tip you of as to where they were created?
sorry for the "late" answer but I think is relevant for people landing here.
was struggling with similar issues ever since session :off was removed from Rails.
I decide to "back-port" it for Rails 2.3+ as a plugin https://github.com/kares/session_off