1212
1313| | |
1414| ---| ---|
15- | ** Type-Safe** | Define sessions as Crystal structs with compile-time guarantees |
15+ | ** Type-Safe** | Define sessions as Crystal classes with compile-time guarantees |
1616| ** Multiple Backends** | Cookie, Memory, Redis, or Clustered Redis—pick what fits |
1717| ** Battle-Tested Security** | AES-256 encryption, HMAC-SHA256, PBKDF2, client binding |
1818| ** Production Resilience** | Circuit breakers, retry logic, graceful degradation |
19- | ** 329+ Tests** | Comprehensive coverage you can rely on |
19+ | ** 346 Tests** | Comprehensive coverage you can rely on |
2020
2121---
2222
@@ -36,22 +36,21 @@ dependencies:
3636require "session"
3737
3838# Define your session data
39- struct UserSession
40- include Session::SessionData
41- property user_id : Int64?
42- property username : String?
39+ class UserSession < Session::Base
40+ property? authenticated : Bool = false
41+ property username : String? = nil
4342end
4443
4544# Configure once
4645Session.configure do |config|
4746 config.secret = ENV["SESSION_SECRET"]
48- config.provider = Session::MemoryStore(UserSession).provider
47+ config.store = Session::MemoryStore(UserSession).new
4948end
5049
5150# Create and use sessions
52- session = Session.provider.create
53- session.data.user_id = 42
54- session.data. username = "alice"
51+ store = Session.config.store.not_nil!
52+ session = store.create
53+ session.username = "alice"
5554```
5655
5756That's it. You're ready to build.
@@ -71,17 +70,17 @@ That's it. You're ready to build.
7170
7271``` crystal
7372# Cookie (stateless, client-side)
74- config.provider = Session::CookieStore(UserSession).provider
73+ config.store = Session::CookieStore(UserSession).new
7574
7675# Memory (development)
77- config.provider = Session::MemoryStore(UserSession).provider
76+ config.store = Session::MemoryStore(UserSession).new
7877
7978# Redis (production)
80- config.provider = Session::RedisStore(UserSession).provider (client: Redis.new)
79+ config.store = Session::RedisStore(UserSession).new (client: Redis.new)
8180
8281# Clustered Redis (high-scale production)
8382config.cluster.enabled = true
84- config.provider = Session::ClusteredRedisStore(UserSession).new(client: Redis.new)
83+ config.store = Session::ClusteredRedisStore(UserSession).new(client: Redis.new)
8584```
8685
8786### Security
@@ -152,7 +151,7 @@ Session.configure do |config|
152151 config.cluster.local_cache_ttl = 30.seconds
153152 config.cluster.local_cache_max_size = 10_000
154153
155- config.provider = Session::ClusteredRedisStore(UserSession).new(
154+ config.store = Session::ClusteredRedisStore(UserSession).new(
156155 client: Redis.new(url: ENV["REDIS_URL"])
157156 )
158157end
@@ -162,26 +161,26 @@ end
162161
163162## API Essentials
164163
165- ### Provider Operations
164+ ### Store Operations
166165
167166``` crystal
168- provider = Session.provider
169-
170- provider .create # New session
171- provider .delete # Destroy session
172- provider .regenerate_id # New ID, keep data (post-login security)
173- provider .valid? # Check validity
174- provider.data # Access your typed session data
175- provider .flash # One-request flash messages
167+ store = Session.config.store.not_nil!
168+
169+ store .create # New session
170+ store .delete # Destroy session
171+ store .regenerate_id # New ID, keep data (post-login security)
172+ store .valid? # Check validity
173+ store.current_session # Access your typed session data
174+ store .flash # One-request flash messages
176175```
177176
178177### Session Object
179178
180179``` crystal
181- session = provider .current_session
180+ session = store .current_session
182181
183182session.session_id # Unique ID
184- session.data # Your SessionData struct
183+ session.username # Your session properties directly
185184session.valid? # Not expired?
186185session.expired? # Past expiration?
187186session.time_until_expiry # Remaining lifetime
@@ -192,11 +191,11 @@ session.touch # Extend expiration
192191
193192``` crystal
194193# Set (available next request)
195- provider .flash["notice"] = "Saved successfully"
196- provider .flash["error"] = "Something went wrong"
194+ store .flash["notice"] = "Saved successfully"
195+ store .flash["error"] = "Something went wrong"
197196
198197# Read (clears after access)
199- provider .flash.now["notice"] # => "Saved successfully"
198+ store .flash.now["notice"] # => "Saved successfully"
200199```
201200
202201### Query & Bulk Operations
@@ -205,13 +204,13 @@ provider.flash.now["notice"] # => "Saved successfully"
205204store = Session::MemoryStore(UserSession).new
206205
207206# Iterate sessions
208- store.each_session { |s| puts s.data. username }
207+ store.each_session { |s| puts s.username }
209208
210209# Find by criteria
211- admins = store.find_by { |s| s.data. roles.includes?("admin") }
210+ admins = store.find_by { |s| s.roles.includes?("admin") }
212211
213212# Bulk delete (e.g., revoke compromised user)
214- store.bulk_delete { |s| s.data. user_id == compromised_id }
213+ store.bulk_delete { |s| s.user_id == compromised_id }
215214```
216215
217216---
@@ -223,11 +222,13 @@ require "http/server"
223222
224223Session.configure do |config|
225224 config.secret = ENV["SESSION_SECRET"]
226- config.provider = Session::MemoryStore(UserSession).provider
225+ config.store = Session::MemoryStore(UserSession).new
227226end
228227
228+ store = Session.config.store.not_nil!
229+
229230server = HTTP::Server.new([
230- Session::SessionHandler.new(Session.provider ),
231+ Session::SessionHandler.new(store ),
231232 YourAppHandler.new,
232233])
233234
@@ -269,8 +270,8 @@ Session.configure do |config|
269270 config.cluster.local_cache_max_size = 10_000
270271
271272 # Callbacks
272- config.on_started = ->(id, data ) { Log.info { "Session #{id} created" } }
273- config.on_deleted = ->(id, data ) { Log.info { "Session #{id} destroyed" } }
273+ config.on_started = ->(id : String, session : Session::Base ) { Log.info { "Session #{id} created" } }
274+ config.on_deleted = ->(id : String, session : Session::Base ) { Log.info { "Session #{id} destroyed" } }
274275
275276 # Metrics
276277 config.metrics_backend = Session::Metrics::LogBackend.new
@@ -290,6 +291,7 @@ Full documentation available at [GitBook](https://azutoolkit.gitbook.io/session)
290291- [ Security Best Practices] ( docs/configuration/security.md )
291292- [ AZU Framework Integration] ( docs/integrations/azu-framework.md )
292293- [ HTTP::Server Integration] ( docs/integrations/http-server.md )
294+ - [ Upgrade Guide] ( UPGRADE.md )
293295
294296---
295297
0 commit comments