Class: Utopia::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/utopia/session.rb,
lib/utopia/session/lazy_hash.rb,
lib/utopia/session/serialization.rb

Overview

A middleware which provides a secure client-side session storage using a private symmetric encrpytion key.

Defined Under Namespace

Classes: LazyHash, PayloadError, Serialization

Constant Summary collapse

MAXIMUM_SIZE =
1024*32
SECRET_KEY =
'UTOPIA_SESSION_SECRET'.freeze
RACK_SESSION =
"rack.session".freeze
CIPHER_ALGORITHM =
"aes-256-cbc"
DEFAULT_EXPIRES_AFTER =

The session will expire if no requests were made within 24 hours:

3600*24
DEFAULT_UPDATE_TIMEOUT =

At least, the session will be updated every 1 hour:

3600

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, session_name: RACK_SESSION, secret: nil, expires_after: DEFAULT_EXPIRES_AFTER, update_timeout: DEFAULT_UPDATE_TIMEOUT, secure: false, maximum_size: MAXIMUM_SIZE, **options) ⇒ Session



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/utopia/session.rb', line 55

def initialize(app, session_name: RACK_SESSION, secret: nil, expires_after: DEFAULT_EXPIRES_AFTER, update_timeout: DEFAULT_UPDATE_TIMEOUT, secure: false, maximum_size: MAXIMUM_SIZE, **options)
  @app = app
  
  @session_name = session_name
  @cookie_name = @session_name + ".encrypted"
  
  if secret.nil? or secret.empty?
    secret = SecureRandom.hex(32)
    warn "#{self.class} secret is #{secret.inspect}, generating transient secret key!" if $VERBOSE
  end
  
  # This generates a 32-byte key suitable for aes.
  @key = Digest::SHA2.digest(secret)
  
  @expires_after = expires_after
  @update_timeout = update_timeout
  
  @cookie_defaults = {
    domain: nil,
    path: "/",
    # The Secure attribute is meant to keep cookie communication limited to encrypted transmission, directing browsers to use cookies only via secure/encrypted connections. However, if a web server sets a cookie with a secure attribute from a non-secure connection, the cookie can still be intercepted when it is sent to the user by man-in-the-middle attacks. Therefore, for maximum security, cookies with the Secure attribute should only be set over a secure connection.
    secure: secure,
    # The HttpOnly attribute directs browsers not to expose cookies through channels other than HTTP (and HTTPS) requests. This means that the cookie cannot be accessed via client-side scripting languages (notably JavaScript), and therefore cannot be stolen easily via cross-site scripting (a pervasive attack technique).
    http_only: true,
  }.merge(options)
  
  @serialization = Serialization.new
  @maximum_size = maximum_size
end

Instance Attribute Details

Returns the value of attribute cookie_defaults.



91
92
93
# File 'lib/utopia/session.rb', line 91

def cookie_defaults
  @cookie_defaults
end

Returns the value of attribute cookie_name.



85
86
87
# File 'lib/utopia/session.rb', line 85

def cookie_name
  @cookie_name
end

#expires_afterObject (readonly)

Returns the value of attribute expires_after.



88
89
90
# File 'lib/utopia/session.rb', line 88

def expires_after
  @expires_after
end

#keyObject (readonly)

Returns the value of attribute key.



86
87
88
# File 'lib/utopia/session.rb', line 86

def key
  @key
end

#update_timeoutObject (readonly)

Returns the value of attribute update_timeout.



89
90
91
# File 'lib/utopia/session.rb', line 89

def update_timeout
  @update_timeout
end

Instance Method Details

#call(env) ⇒ Object



105
106
107
108
109
110
111
112
113
# File 'lib/utopia/session.rb', line 105

def call(env)
  session_hash = prepare_session(env)

  status, headers, body = @app.call(env)

  update_session(env, session_hash, headers)

  return [status, headers, body]
end

#freezeObject



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/utopia/session.rb', line 93

def freeze
  return self if frozen?
  
  @cookie_name.freeze
  @key.freeze
  @expires_after.freeze
  @update_timeout.freeze
  @cookie_defaults.freeze
  
  super
end