Class: Cybertrain::Session
- Inherits:
-
Object
- Object
- Cybertrain::Session
- Defined in:
- cybertrain/session.rb
Overview
A cookie-store session: a flat Hash<String,String> that round-trips through a signed, base64-encoded cookie value. Design D8 restricts values to String – there is no marshalling format to smuggle other types through, so nothing else needs to be ruled out at the type level.
Controller#session in an action. Keys and values are Strings (a
Symbol key is its name; a value is stored as value.to_s, so
session[:user_id] = 5 reads back as "5").
The cookie is signed with secret_key_base (HMAC-SHA256), not
encrypted: the client can read it, but a changed or forged cookie is
dropped and the request starts with an empty session. It is sent only
when the session changed, as _cybertrain_session with Path=/;
HttpOnly; SameSite=Lax, Secure in production and a two-week Max-Age
(the name, the Max-Age and Secure are Config settings).
"_csrf_token" and "_flash" are the framework’s keys.
Instance Method Summary collapse
-
#[](key) ⇒ String?
-
#[]=(key, value) ⇒ String
-
#clear ⇒ Object
Empties the session, the CSRF token included, so forms rendered before it no longer submit (403).
-
#csrf_token! ⇒ String
Returns this session’s CSRF token, minting and storing one the first time it is asked for.
-
#delete(key) ⇒ String?
The removed value.
-
#key?(key) ⇒ Boolean
-
#keys ⇒ Array<String>
-
#to_h ⇒ Hash{String => String}
A copy.
Instance Method Details
#[](key) ⇒ String?
43 44 45 |
# File 'cybertrain/session.rb', line 43 def [](key) @data[key.to_s] end |
#[]=(key, value) ⇒ String
51 52 53 54 55 56 |
# File 'cybertrain/session.rb', line 51 def []=(key, value) k = key.to_s v = value.to_s @changed = true unless @data[k] == v @data[k] = v end |
#clear ⇒ Object
Empties the session, the CSRF token included, so forms rendered before it no longer submit (403). Use it on sign-out.
83 84 85 86 |
# File 'cybertrain/session.rb', line 83 def clear @changed = true unless @data.empty? @data.clear end |
#csrf_token! ⇒ String
Returns this session’s CSRF token, minting and storing one the first
time it is asked for. Forms built with form_with and button_to
already carry it; send it yourself as the X-CSRF-Token header or an
authenticity_token parameter from JavaScript or a hand-written form.
This is a typed instance method (rather than a
module method taking a Session argument) so Spinel resolves self
statically at every call site: a free function taking session as a
plain parameter widens it to an untyped poly value once it is called
through a real SessionStore -> Context chain, and then
session[TOKEN_KEY] = token silently does nothing
(tests: test/csrf_chain.rb, test/csrf_conditional.rb).
114 115 116 117 118 119 120 121 |
# File 'cybertrain/session.rb', line 114 def csrf_token! token = @data[CSRF_TOKEN_KEY] if token.nil? || token.empty? token = Crypto.random_token self[CSRF_TOKEN_KEY] = token end token end |
#delete(key) ⇒ String?
Returns the removed value.
61 62 63 64 65 |
# File 'cybertrain/session.rb', line 61 def delete(key) k = key.to_s @changed = true if @data.key?(k) @data.delete(k) end |
#key?(key) ⇒ Boolean
70 71 72 |
# File 'cybertrain/session.rb', line 70 def key?(key) @data.key?(key.to_s) end |
#keys ⇒ Array<String>
76 77 78 |
# File 'cybertrain/session.rb', line 76 def keys @data.keys end |
#to_h ⇒ Hash{String => String}
Returns a copy.
90 91 92 |
# File 'cybertrain/session.rb', line 90 def to_h @data.dup end |