Class Index [+]

Quicksearch

Merb::CookieSession

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

Constants

MAX

Cookies can typically store 4096 bytes.

DIGEST

Attributes

_original_session_data[RW]

:api: private

Public Class Methods

generate() click to toggle source

Generates a new session ID and creates a new session.

Returns

SessionContainer

The new session.

:api: private

    # File lib/merb-core/dispatch/session/cookie.rb, line 46
46:       def generate
47:         self.new(Merb::SessionMixin.rand_uuid, "", Merb::Request._session_secret_key)
48:       end
new(session_id, cookie, secret) click to toggle source

Parameters

session_id

A unique identifier for this session.

cookie

The raw cookie data.

secret

A session secret.

Raises

ArgumentError

blank or insufficiently long secret.

:api: private

    # File lib/merb-core/dispatch/session/cookie.rb, line 78
78:     def initialize(session_id, cookie, secret)
79:       super session_id
80:       if secret.blank? || secret.length < 16
81:         msg = "You must specify a session_secret_key in your init file, and it must be at least 16 characters"
82:         Merb.logger.warn(msg)
83:         raise ArgumentError, msg
84:       end
85:       @secret = secret
86:       self.update(unmarshal(cookie))
87:     end
setup(request) click to toggle source

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

Parameters

request

The Merb::Request that came in from Rack.

Returns

SessionContainer

a SessionContainer. If no sessions were found,

a new SessionContainer will be generated.

:api: private

    # File lib/merb-core/dispatch/session/cookie.rb, line 60
60:       def setup(request)
61:         session = self.new(Merb::SessionMixin.rand_uuid,
62:           request.session_cookie_value, request._session_secret_key)
63:         session._original_session_data = session.to_cookie
64:         request.session = session
65:       end

Public Instance Methods

finalize(request) click to toggle source

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

request object created from Rack environment.

:api: private

     # File lib/merb-core/dispatch/session/cookie.rb, line 98
 98:     def finalize(request)
 99:       if @_destroy
100:         request.destroy_session_cookie
101:       elsif _original_session_data != (new_session_data = self.to_cookie)
102:         request.set_session_cookie_value(new_session_data)
103:       end
104:     end
regenerate() click to toggle source

Regenerate the session_id.

:api: private

     # File lib/merb-core/dispatch/session/cookie.rb, line 109
109:     def regenerate
110:       self.session_id = Merb::SessionMixin.rand_uuid
111:     end

Protected Instance Methods

serialize() click to toggle source

Serialize current session data as a Hash. Uses Base64 encoding for integrity.

Returns

String

Base64 encoded dump of the session hash.

:api: private

     # File lib/merb-core/dispatch/session/cookie.rb, line 219
219:     def serialize
220:       Base64.encode64(Marshal.dump(self.to_hash)).chop
221:     end
unserialize(data) click to toggle source

Unserialize the raw cookie data to a Hash

Returns

Hash

the session hash Base64 decoded from the data dump.

:api: private

     # File lib/merb-core/dispatch/session/cookie.rb, line 229
229:     def unserialize(data)
230:       Marshal.load(Base64.decode64(data)) rescue {}
231:     end

Private Instance Methods

generate_digest(data) click to toggle source

Generate the HMAC keyed message digest. Uses SHA1.

Returns

String

an HMAC digest of the cookie data.

:api: private

     # File lib/merb-core/dispatch/session/cookie.rb, line 148
148:     def generate_digest(data)
149:       OpenSSL::HMAC.hexdigest(DIGEST, @secret, data)
150:     end
secure_compare(a, b) click to toggle source

Securely compare two digests using a constant time algorithm. This avoids leaking information about the calculated HMAC

Based on code by Michael Koziarski github.com/rails/rails/commit/674f780d59a5a7ec0301755d43a7b277a3ad2978

Parameters

a, b<~to_s>

digests to compare.

Returns

Boolean

Do the digests validate?

     # File lib/merb-core/dispatch/session/cookie.rb, line 163
163:     def secure_compare(a, b)
164:       if a.length == b.length
165: 
166:         # unpack to forty characters.
167:         # needed for 1.8 and 1.9 compat
168:         a_bytes = a.unpack('C*')
169:         b_bytes = b.unpack('C*')
170: 
171:         result = 0
172:         for i in 0..(a_bytes.length - 1)
173:           result |= a_bytes[i] ^ b_bytes[i]
174:         end
175:         result == 0
176:       else
177:         false
178:       end
179:     end
unmarshal(cookie) click to toggle source

Unmarshal cookie data to a hash and verify its integrity.

Parameters

cookie<~to_s>

The cookie to unmarshal.

Raises

TamperedWithCookie

The digests don’t match.

Returns

Hash

The stored session data.

:api: private

     # File lib/merb-core/dispatch/session/cookie.rb, line 194
194:     def unmarshal(cookie)
195:       if cookie.blank?
196:         {}
197:       else
198:         data, digest = Merb::Parse.unescape(cookie).split('--')
199:         return {} if data.blank? || digest.blank?
200:         unless secure_compare(generate_digest(data), digest)
201:           clear
202:           unless Merb::Config[:ignore_tampered_cookies]
203:             raise TamperedWithCookie, "Maybe the site's session_secret_key has changed?"
204:           end
205:         end
206:         unserialize(data)
207:       end
208:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.