Sesiones y Cookies en Sinatra

Donde

Introducción

A session is used to keep state during requests. If activated, you have one session hash per user session:

enable :sessions

get '/' do
  "value = " << session[:value].inspect
end

get '/:value' do
  session[:value] = params[:value]
end
  1. Note that enable :sessions actually stores all data in a cookie
  2. This might not always be what you want (storing lots of data will increase your traffic, for instance)
  3. You can use any Rack session middleware: in order to do so, do not call enable :sessions, but instead pull in your middleware of choice as you would any other middleware:

    use Rack::Session::Pool, :expire_after => 2592000
    
    get '/' do
      "value = " << session[:value].inspect
    end
    
    get '/:value' do
      session[:value] = params[:value]
    end
    
  4. To improve security, the session data in the cookie is signed with a session secret
  5. A random secret is generated for you by Sinatra
  6. However, since this secret will change with every start of your application, you might want to set the secret yourself, so all your application instances share it:
    set :session_secret, 'super secret'
    
    If you want to configure it further, you may also store a hash with options in the sessions setting:
    set :sessions, :domain => 'foo.com'
    
  7. Just use session.clear to destroy the session.
    get '/login' do
        session[:username] = params[:username]
        "logged in as #{session[:username]}"
      end
    
      get '/logout' do
        old_user = session[:username]
        session.clear
        "logged out #{old_user}"
      end
    

Cookies

  1. According to the Computer Science definition, a cookie, which is also known as an HTTP cookie, a tracking cookie, or a browser cookie, is a piece of text, no bigger than 4 kilobytes, which is stored on the user’s computer by a web server via a web browser
  2. It is a key-value pair structure, which is designed to retain specific information such as
  3. This mechanism, which was developed by Netscape in the distant 1994, provides a way to receive information from a web server and to send it back from the web browser absolutely unchanged
  4. This system complements the stateless nature of the HTTP protocol as it provides enough memory to store pieces of information during HTTP transactions

  5. When you try to access a web site, your web browser connects to a web server and it sends a request for the respective page
  6. Then the web server replies by sending the requested content and it simultaneously stores a new cookie on your computer
  7. Every time the web browser requests web pages from the web server, it always sends the respective cookies back to the web server
  8. The process takes place as described, if the web browser supports cookies and the user allows their usage
  9. Only the web server can modify one or more of the cookie values
  10. Then it sends them to the web browser upon replying to a specific request

  11. According to the RFC2965 specification, cookies are case insensitive
  12. A set of defined properties is inherent to the cookie structure Those properties include: an expiration date, a path and a domain
  13. The first attribute requires a date defined in Wdy, DD-Mon-YYYY HH:MM:SS GMT format
  14. The rest of the cookie characteristics require a path and/or a domain defined as a string
  15. Let’s take a look at this example:

    Cookie: key0=value0; ...; keyX=valueX; expires=Wed, 23-Sep-2009 23:59:59 GMT; path=/; domain=.yoursite.com
    

  16. When the expiration date is defined, your cookie will be persistent as it will reoccur in different sessions until the set expiration date has been reached
  17. If the expiration date has not been defined in the cookie, it will occur until the end of your current session or when you close your web browser
  18. If the path and/or the domain attributes have been defined in your cookie, then the web server limits the scope of the cookie to that specific domain, sub-domain or path

Ejemplo con Sesiones

require 'rubygems'
require 'sinatra'
require 'haml'

enable :sessions

get '/' do
  session["user"] ||= nil
  haml :index
end

get '/introduction' do
  haml :introduction
end

post '/introduction' do
  session["user"] = params[:name]
  redirect '/'
end

get '/bye' do
  session["user"] = nil
  haml :bye
end

Ejemplo con Cookies

  1. This example will demonstrate how to directly manage cookies through the request and response singletons provided by Sinatra
  2. You will see in the following example that the previously described process involving the use cookies is clearly implemented
  3. This technique is recommended when your application requires to use persistent and/or scoped cookies
  4. In this example, the application uses two persistent cookies, which expire at the same time, in order to store and manage different configuration data

require 'sinatra'
require 'haml'

get '/' do
  @@expiration_date = Time.now + (60 * 2) \
  unless request.cookies.key?('some_options') && request.cookies.key?('other_options')
  haml :index
end

get '/some_options' do
  @some_cookie = request.cookies["some_options"]
  haml :some_options
end

post '/some_options' do  
  response.set_cookie('some_options', :value => cookie_values(params), :expires => @@expiration_date)
  redirect '/'
end

get '/other_options' do
  @other_cookie = request.cookies["other_options"]
  haml :other_options
end

post '/other_options' do
  response.set_cookie('other_options', :value => cookie_values(params),:expires => @@expiration_date)
  redirect '/'
end

helpers do
  def cookie_values(parameters)
    values = {}
    parameters.each do |key, value|
      case key
      when 'options'
        values[value] = true
      else
        values[key] = true
      end
    end
    values
  end
end

Problemas

  1. I'm not sure why but my session gets wiped out every request?
  2. To keep sessions consistent you need to set a session secret, e.g.:

    set :session_secret, 'super secret'
    
    When it's not set sinatra generates random one on application start and shotgun restarts application before every request.

Véanse

  1. Daily Ruby Tips #60 – Simple Use of Sessions in Sinatra May 6, 2013
  2. La sección Cookies en Rack 31.8.
  3. Cookie-based Sessions in Sinatra by JULIO JAVIER CICCHELLI on SEPTEMBER 30, 2009 RubyLearning Blog. El código está en un Gist en GitHub



Subsecciones
Casiano Rodriguez León 2015-01-07