Sessions for Idiots

Overview

The problem is authentication for web applications. We want to support the notion of a logged in user as opposed to a not logged in user. The logged in user should be able to login once to the web application at session.com, close their browser, go out to lunch, and revisit session.com without having to log in again.

Goals

  • Understand what a Session is and how it is implemented at a high level.
  • Explore an example implementation in Ruby.

Given

  • We can log someone in using just browser interactions, and HTTP messages (requests/responses).
  • We can tell if someone is logged in using just browser interactions, and HTTP messages.

Check This Out

  • RFC 6265 - Section 3 - Overview - This IETF standards track document formulates the problem as one of state management, i.e. how can we support a state of being logged in across separate visits to our website?

To store state, the origin server includes a Set-Cookie header in an HTTP response. In subsequent requests, the user agent returns a Cookie request header to the origin server. The Cookie header contains cookies the user agent received in previous Set-Cookie headers.

####
# Diagram below copied from RFC 6265
####

== Server -> User Agent ==

Set-Cookie: SID=31d4d96e407aad42

== User Agent -> Server ==

Cookie: SID=31d4d96e407aad42  

A bit about Rack

ASIDE: Rack allows us to do this:

require 'rack'

app = Proc.new do |env|  
  ['200', {'Content-Type' => 'text/html'}, ['A barebones rack app.']]
end

Rack::Handler::WEBrick.run app  
  • Where app is any object that responds to the call method (such as the Proc in the example) and returns an array with a response code, hash of response headers, and a response body.

  • Rack also provides env, which is an environment hash that comes along with each request. It stores data entered into forms, URL parameters, request headers (where the Cookies are at), and all kinds of good stuff.

  • As far as Sessions go, Rack also implements the Rack::Session::Abstract::ID class, which inherits from Rack::Session::Abstract::Persisted. ID has the method #write_session, which writes a session id sid to an env hash in the form of a "Set-Cookie" header. That env hash of course contributes to the response headers sent back to the user.