Rails 3 session & cookie how to persist session id cookie - ruby-on-rails

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)

Related

Rails 4 external redirection and sessions issue

I am trying to build a website in Rails 4 to track users redirects and site element views.
I decided to use session ids which I believe are quite unique in the short term but I'm having a strange issue.
Example procedure:
user follows a redirect, the system stores this action with a Session ID, let's say xxx
user reaches destination page, which contains a tracker, the system stores this action with ANOTHER Session ID, yyy
user reaches another page which also contains a tracker, the system stores this action with Session ID yyy
After the second action is stored, the session ID stays the same yyy for every request after that, but I need to have the same session ID every time.
In session I also store a SecureRandom.hex generated code, which also changes from the first to the second request (which is not a surprise, since the session ID changes).
I also tried using a cookie, same result.
Please notice that these redirects are external, but all the requests are then made to the same domain (exactly the same, without www and in https).
Any idea?
Thanks in advance.
Update
this is the source code responsible for managing redirects:
before_action :load_redirect, :only => [:http_redirect]
def http_redirect
raise ActionController::RoutingError.new('Redirect has been disabled') unless #redir.enabled
ua = UserAction.create(
:session_id => session.id,
:user_agent => request.user_agent,
:trackable => #redir,
:ip_address => request.remote_ip,
:referer => request.referer
)
redirect_to #redir.destination_url
end
private
def load_redirect
#redir = Redirect.find(params[:id])
end
UPDATE:
Since you are using an iframe (per comment discussion below) for tracking code, the issue is likely that on the external site cookies are not being passed from parent page to the iframe because the iframes origin (domain) is different from the parent page.
OLD ANSWER:
(Still could be helpful for others debugging similar issues)
Source code would help. Without that, here are a few things to try:
Try disabling CSRF protection for the external tracking link action (I'm assuming it POSTs or PUTs data from an external source). CSRF protection could be creating a new or null session for those requests. Put this in the controller that contains the action accepting data from the external source:
protect_from_forgery :except => [:your_action]
The redirect (especially if it's a 301) could be cached in the browser you are using, hence having a different cookie and session than the request your tracking code makes. The stale cookie would be part of the cached redirect.
Try putting cache control headers on your controller action that does the redirect.
response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '0'
Your browser may not support setting cookies on a redirect, or possibly third-party cookies. Try in a different modern browser?
There could be a bug in your code. If these solutions don't work, maybe post it?

how to get the persistent cookie value and session cookie value in rails application

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

Can't understand sessions in Rails

Please don't bit my for my misunderstanding.
The sessions are very new for me, and i have some problems.
Okay i read many information about sessions and especially rails session. But this don't give me right imagine about sessions.
Did i understand right, when users send request to server (get) -> Server create a new session (and store this some file in hard drive with session id), session id -> is a random generated num? so, server create a new session (and store session on drive) after this server send back answer to client and set session_id in cookies?
Ok, i debug some params and see some results:
debug(session):
{:_csrf_token=>"jeONIfNxFmnpDn/xt6I0icNK1m3EB3CzT9KMntNk7KU=", :session_id=>"06c5628155efaa6446582c491499af6d", "flash"=>{}}
debug(cookies):
{"remember_user_token"=>"1::3GFRFyXb83lffzwPDPQd", "_blog_session"=>"BAh7CDoQX2NzcmZfdG9rZW4iMWplT05JZk54Rm1ucERuL3h0NkkwaWNOSzFtM0VCM0N6VDlLTW50Tms3S1U9Og9zZXNzaW9uX2lkIiUwNmM1NjI4MTU1ZWZhYTY0NDY1ODJjNDkxNDk5YWY2ZCIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA==--348c88b594e98f4bf6389d94383134fbe9b03095"}
Okay, i know, what _csrf_token helps to prevent csrf.
session_id -> is id of the session which stored on hard drive (by default)
but what is _blog_session in cookies?
also, remeber_user_token containes my id (1::*) and what about second part, what is it?
Sorry for this stupid questions, i know what i can easy use any nice auth-plugins (authlogic/clearance/devise), but i want to fully understand sessions.
Thank you.
(also sorry for my english, this is not my native language)
remember_user_token is probably set by your authentication plugin, it is encrypted string, which is stored in users table and is used to authenticate him. Details can vary between plugins.
Second part: you are probably using cookie based session store (it is default),
So, _blog_session stores your encrypted session data.
More about cookie based sessions here and here.
The name "_blog_session" is set in config/initializers/session_store.rb
It looks like:
# Your secret key for verifying cookie session data integrity.
# If you change this key, all old sessions will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
ActionController::Base.session = {
:key => '_blogs_session',
:secret => '07fb6f0d41af4ae06aebb1696fcbb5a5398d4a08570744a4cd53ff237020c43a2022b4041d617d95bcf3f5c4601c7e6c1646eecfc157cc200e7dfedd7d7c6813'
}

How to conditionally assign ActionController::Base.session in rails 2.3.3

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

How to I dynamically set the expiry time for a cookie-based session in Rails

I'm currently using the ActiveRecord-based session store for my Rails app and I have a background process which clears out inactive sessions every 30 minutes.
I'd like to switch to Rails' new cookie-based session store but how do I set the expiry time of the session to 30 minutes, as opposed to the default 'at end of session' value?
I stumbled across this question after a conversation in the office. Just for the sake of completeness, I've discovered that it is possible to expire sessions after a period of inactivity and it's built into Rails. In config/environment.rb, do something along the lines of:
config.action_controller.session = {
:key => 'whatever',
:secret => 'nottellingyou',
:expire_after => 30.minutes
}
Check out lib/action_controller/session/cookie_store.rb#114 for the (apparently undocumented) option in action. Looks like it's been around since the move to Rack sessions back in December 2008.
Ideally, you'd want to add something like this to environment.rb:
session :session_expires => 1.day.from_now
But that won't work because the code is only run once when the APP is started and thus the next day all your sessions are being created with an expiration in the past.
I usually set the session_expires to some time far in the future (6 months). Then manually set and check a session[:expires] date in a before_filter on my application controller and reset the session when that date has passed.
This makes it VERY easy to add a 'Keep me logged in for ___' option when signing in, you just set session[:expires] = Time.now + ___
After a lot of pain & experimenting, found in Rails 3.x, you need to set your custom session parameters in an after filter in every request
class ApplicationController < ActionController::Base
after_filter :short_session
...
def short_session
request.session_options = request.session_options.dup
request.session_options[:expire_after] = 1.minute
request.session_options.freeze
end
The session options page on the Rails wiki hints that this is only possible through a plugin:
Set the session cookie expire time
Unfortunately Rails has no way to dynamically set the expiry time of the session cookie. So it is recommended that you use the following plugin, which allows you to accomplish it: http://blog.codahale.com/2006/04/08/dynamic-session-expiration-times-with-rails/
Of course take into account that the plugin is old, and may not work with your current version of Rails (I haven't looked at the specifics)
Use this, it's working for me in rails 2.1.x:
SlidingSessions
I currently have cookies set to expire exactly 2 weeks after a user logs in, and setting it to 30 minutes is simple.
You could try adding the following line to your environment.rb file:
session :session_key => 'my_session_key'
session :session_expires => 1.day.from_now
Alternatively, you can set the session options as follows:
ActionController::Base.session_options[:session_expires] = 1.day.from_now
I've not tested this thouroughly, so YMMV.

Resources