Maintaining same session for a user across different PCs

Hi,

I’m trying to make a simple shopping cart, where I want to maintain
state when a use logs in from different location. Consider the
following :

  1. ‘foo’ logs in from home pc and add ‘bar’ item to the cart.
  2. ‘foo’ goes to office and logs in from office PC.
  3. Now I want only one session for ‘foo’, so that when he logs in from
    office PC, he sees ‘bar’ already added in his shopping cart.

I can probably store session id in User table. But I’m not sure how to
go about this.

Any inputs would be great.

Thanks,
Pratik

Pratik <pratiknaik@…> writes:

go about this.
Hello Pratik,

A ‘session’ in Rails (and also in anything else using CGI::Session)
is tied to a session_id. This gets ‘born’ everytime a browser
currently unknown to Rails sends a request to the web server. ‘Unknown’
in this sense means that the browser does not (currently)
have a cookie called ‘_session_id’ (or, if it does, the value of it does
not

match any currently known session). If the browser instance does not
have this

matching session id, then it gets given one right away (and a matching
session

object is created on the rails side).

[Aside: The session objects are identified by an id (not a number)
that is generated by the cgi module. The id is generated in such way
as to be one-time unique. It does this by creating (by default) a 32
hex character key (which means there are 16^32 possible combinations).
It is an MD5 hash based upon the time, a random number, and a
constant string. An example is “d53cb20abe8c3d11”. ]

The _session_id cookie is set to last for the life of the
browser. It does not go away until the user closes the browser
(or manually deletes it). Just logging out (but leaving the
browser open) will leave the session around.

The upshot of all this is that information in the session object
is normally only available to that specific browser session.
So, in your scenario, logging in on another browser will not
(of itself) make that information available to the newly logged
in browser (in fact that will generate its own new session).

To keep information persisted for an indentified user, you are
going to have to put it into a db table (easy enough) or a file
(harder). To get the current session values persisted in this way,
I see a number of options:

[1] Know which specific values you want to store and keep
them current in the db as the session values are updated.

[2] Assuming the user logs out cleanly (hard to rely on),
the logout action could grab the session file and store it
in a column in the user table. Then on re-login somewhere
else, it could be pulled out and used the replaces the contents
of the new (initial) session file. This would require direct
reads and writes to session files and would likely be frowned
on since you really need to know more lower level details.

[3] Unmarshall the session file and convert the resulting hash
to (say) YAML and store that in the user table. Then, on the
fresh login, bring the values back from YAML and replace
specific session values from that.

It’s all pretty tricky, but such a ‘session tranference’ is going
beyond what sessions were built for (ephemeral browser state).

You can get the session_id like this: cookies[:_session_id]

Session files are kept in:

SessDir = RUBY_PLATFORM =~ /mswin32/ ? ENV[‘TEMP’] : ‘/tmp’

prior to Rails 1.1, and for Rails 1.1

SessDir = ActionController::Base.session_options[:tmpdir]

You can grab session files like this:
files = Dir.glob("#{SessDir}/ruby_sess.*")

the suffix is the session_id. e.g. ruby_sess.d53cb20abe8c3d11

Load them up like this:

sess = Marshal.load(File.read(sfile))

Set values:

sess[“hash”][:expired] = ‘true’

Write them back

ssfile = File.open(sfile, “w+”)
ssfile.write(Marshal.dump(sess))
ssfile.close

– Mike B.

Thanks a lot Mike for your detailed reply. That helped a lot :slight_smile:

-Pratik

On 6/20/06, Pratik [email protected] wrote:

go about this.
You don’t really need to maintain a single session here. You should
consider storing the cart in the database, rather than keeping it only
in memory in the session.

– James