# Note that changing digest or secret invalidates all existing sessions!
classCGI::Session::CookieStore
# Cookies can typically store 4096 bytes.
MAX=4096
SECRET_MIN_LENGTH=30# characters
# Raised when storing more than 4K of session data.
classCookieOverflow<StandardError;end
# Raised when the cookie fails its integrity check.
classTamperedWithCookie<StandardError;end
# Called from CGI::Session only.
definitialize(session,options={})
# The session_key option is required.
ifoptions['session_key'].blank?
raiseArgumentError,'A session_key is required to write a cookie containing the session data. Use config.action_controller.session = { :session_key => "_myapp_session", :secret => "some secret phrase" } in config/environment.rb'
end
# The secret option is required.
ensure_secret_secure(options['secret'])
# Keep the session and its secret on hand so we can read and write cookies.
@session,@secret=session,options['secret']
# Message digest defaults to SHA1.
@digest=options['digest']||'SHA1'
# Default cookie options derived from session settings.
# Set no_hidden and no_cookies since the session id is unused and we
# set our own data cookie.
options['no_hidden']=true
options['no_cookies']=true
end
# To prevent users from using something insecure like "Password" we make sure that the
# secret they've provided is at least 30 characters in length.
defensure_secret_secure(secret)
# There's no way we can do this check if they've provided a proc for the
# secret.
returntrueifsecret.is_a?(Proc)
ifsecret.blank?
raiseArgumentError,%Q{A secret is required to generate an integrity hash for cookie session data. Use config.action_controller.session = { :session_key => "_myapp_session", :secret => "some secret phrase of at least #{SECRET_MIN_LENGTH} characters" } in config/environment.rb}
end
ifsecret.length<SECRET_MIN_LENGTH
raiseArgumentError,%Q{Secret should be something secure, like "#{CGI::Session.generate_unique_id}". The value you provided, "#{secret}", is shorter than the minimum length of #{SECRET_MIN_LENGTH} characters}
end
end
# Restore session data from the cookie.
defrestore
@original=read_cookie
@data=unmarshal(@original)||{}
end
# Wait until close to write the session data cookie.
defupdate;end
# Write the session data cookie if it was loaded and has changed.