Class: Merb::CookieSession

Inherits:
SessionContainer show all
Defined in:
lib/merb-core/dispatch/session/cookie.rb

Overview

If you have more than 4K of session data or don’t want your data to be visible to the user, pick another session store.

CookieOverflow is raised if you attempt to store more than 4K of data. TamperedWithCookie is raised if the data integrity check fails.

A message digest is included with the cookie to ensure data integrity: a user cannot alter session data without knowing the secret key included in the hash.

To use Cookie Sessions, set in config/merb.yml

:session_secret_key - your secret digest key
:session_store: cookie

Defined Under Namespace

Classes: CookieOverflow, TamperedWithCookie

Constant Summary collapse

MAX =

Cookies can typically store 4096 bytes.

4096
DIGEST =

or MD5, RIPEMD160, SHA256?

OpenSSL::Digest::Digest.new('SHA1')

Instance Attribute Summary collapse

Attributes inherited from SessionContainer

#needs_new_cookie, #session_id

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from SessionContainer

#clear!, inherited

Constructor Details

#initialize(session_id, cookie, secret) ⇒ CookieSession

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parameters

session_id<String>

A unique identifier for this session.

cookie<String>

The raw cookie data.

secret<String>

A session secret.

Raises

ArgumentError

blank or insufficiently long secret.



77
78
79
80
81
82
83
84
85
86
# File 'lib/merb-core/dispatch/session/cookie.rb', line 77

def initialize(session_id, cookie, secret)
  super session_id
  if secret.blank? || secret.length < 16
    msg = "You must specify a session_secret_key in your init file, and it must be at least 16 characters"
    Merb.logger.warn(msg)
    raise ArgumentError, msg
  end
  @secret = secret
  self.update(unmarshal(cookie))
end

Instance Attribute Details

#_original_session_dataObject

Returns the value of attribute _original_session_data.



33
34
35
# File 'lib/merb-core/dispatch/session/cookie.rb', line 33

def _original_session_data
  @_original_session_data
end

Class Method Details

.generateObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Generates a new session ID and creates a new session.

Returns

SessionContainer

The new session.



45
46
47
# File 'lib/merb-core/dispatch/session/cookie.rb', line 45

def generate
  self.new(Merb::SessionMixin.rand_uuid, "", Merb::Request._session_secret_key)
end

.setup(request) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Set up a new session on request: make it available on request instance.

Parameters

request<Merb::Request>

The Merb::Request that came in from Rack.

Returns

SessionContainer

a SessionContainer. If no sessions were found,

a new SessionContainer will be generated.



59
60
61
62
63
64
# File 'lib/merb-core/dispatch/session/cookie.rb', line 59

def setup(request)
  session = self.new(Merb::SessionMixin.rand_uuid,
    request.session_cookie_value, request._session_secret_key)
  session._original_session_data = session.to_cookie
  request.session = session
end

Instance Method Details

#finalize(request) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Teardown and/or persist the current session.

If @_destroy is true, clear out the session completely, including removal of the session cookie itself.

Parameters

request<Merb::Request>

request object created from Rack environment.



97
98
99
100
101
102
103
# File 'lib/merb-core/dispatch/session/cookie.rb', line 97

def finalize(request)
  if @_destroy
    request.destroy_session_cookie
  elsif _original_session_data != (new_session_data = self.to_cookie)
    request.set_session_cookie_value(new_session_data)
  end
end

#regenerateObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Regenerate the session_id.



108
109
110
# File 'lib/merb-core/dispatch/session/cookie.rb', line 108

def regenerate
  self.session_id = Merb::SessionMixin.rand_uuid
end

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create the raw cookie string; includes an HMAC keyed message digest.

Returns

String

Cookie value.

Raises

CookieOverflow

More than 4K of data put into session.

Notes

Session data is converted to a Hash first, since a container might choose to marshal it, which would make it persist attributes like ‘needs_new_cookie’, which it shouldn’t.



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/merb-core/dispatch/session/cookie.rb', line 126

def to_cookie
  unless self.empty?
    data = self.serialize
    value = Merb::Request.escape "#{data}--#{generate_digest(data)}"
    if value.size > MAX
      msg = "Cookies have limit of 4K. Session contents: #{data.inspect}"
      Merb.logger.error!(msg)
      raise CookieOverflow, msg
    end
    value
  end
end