clowk 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +25 -0
- data/lib/clowk/authenticable.rb +28 -5
- data/lib/clowk/configuration.rb +20 -0
- data/lib/clowk/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a1fa17ef38ffc2cce253e598ab2c2478ba05f5f7c638601ec833bafa00377ebc
|
|
4
|
+
data.tar.gz: 396b0e5c36dcaa01a10397f6227af24dcdf5274a06145222da54855aba71a076
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1fd3f7de008dd50644494e85e0771113ae98be1efdc1abcae7d97888b6af84f7aa2f5fd086aa711d3be4b2984b0a626c9bdddc5d66c6c8bc41955b21325c3717
|
|
7
|
+
data.tar.gz: 36067b774a1d57d833909bcee4316d29a25ee5a907b03063f8ee52545adbf36b09a9857b4b374065a60956f2a5a386044138592b9643e0cf5a7b2f48dec50da8
|
data/README.md
CHANGED
|
@@ -272,6 +272,31 @@ with no round trip at all.
|
|
|
272
272
|
Both ends — the broker said inactive, the ceiling passed — go through
|
|
273
273
|
`config.on_session_expired` when you set one.
|
|
274
274
|
|
|
275
|
+
### Where the token is kept
|
|
276
|
+
|
|
277
|
+
Clowk writes the token to its own cookie, and — by default, as every version
|
|
278
|
+
before 0.9 did — mirrors a copy into the app's Rails session.
|
|
279
|
+
|
|
280
|
+
```ruby
|
|
281
|
+
config.token_store = :cookie # Clowk's cookie only
|
|
282
|
+
config.token_store = :session # also mirrored into the session (the default)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
The copy is not free. A Rails session lives in **one** cookie with about 4096
|
|
286
|
+
bytes to its name, and in production, where tokens are RS256, the token is most
|
|
287
|
+
of what a session weighs. Hand a browser more than it will hold and it discards
|
|
288
|
+
the whole cookie in silence — no error server-side, none in the console, the
|
|
289
|
+
previous cookie simply stays. Everything written on that request goes with it: a
|
|
290
|
+
flash message, a selected tenant, a CSRF rotation. What a person sees is a button
|
|
291
|
+
that does nothing.
|
|
292
|
+
|
|
293
|
+
Under `:cookie` the session keeps the claims and the sign-in time, nothing else.
|
|
294
|
+
`current_token` reads Clowk's cookie instead, which is where an API-only app has
|
|
295
|
+
always read it from. Sessions written before the switch are pruned on their next
|
|
296
|
+
request, so an app does not have to wait for everyone to sign out.
|
|
297
|
+
|
|
298
|
+
The default stays `:session` so an upgrade changes nothing until you ask.
|
|
299
|
+
|
|
275
300
|
### Token verification
|
|
276
301
|
|
|
277
302
|
Tokens signed with `RS256` are verified against Clowk's public key set, fetched
|
data/lib/clowk/authenticable.rb
CHANGED
|
@@ -90,10 +90,17 @@ module Clowk
|
|
|
90
90
|
def clowk_current_resource
|
|
91
91
|
@clowk_current_resource ||= begin
|
|
92
92
|
payload = stored_user_payload || verified_request_payload
|
|
93
|
+
|
|
94
|
+
drop_mirrored_token!
|
|
95
|
+
|
|
93
96
|
payload ? Current.new(payload) : nil
|
|
94
97
|
end
|
|
95
98
|
end
|
|
96
99
|
|
|
100
|
+
# The session first, which holds a copy only under token_store :session —
|
|
101
|
+
# and, for one request after an app switches to :cookie, in a session
|
|
102
|
+
# written before the switch. drop_mirrored_token! clears those. Clowk's own
|
|
103
|
+
# cookie is the source either way.
|
|
97
104
|
def current_token
|
|
98
105
|
stored_session&.dig("token") || extracted_token
|
|
99
106
|
end
|
|
@@ -311,11 +318,10 @@ module Clowk
|
|
|
311
318
|
store = clowk_session_store
|
|
312
319
|
return if store.nil?
|
|
313
320
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
}
|
|
321
|
+
claims = {user: payload, signed_in_at: Time.now.to_i}
|
|
322
|
+
|
|
323
|
+
store[Clowk.config.session_key] =
|
|
324
|
+
(Clowk.config.token_store == :cookie) ? claims : claims.merge(token:)
|
|
319
325
|
|
|
320
326
|
clowk_cookie_jar&.[]=(Clowk.config.cookie_key, {
|
|
321
327
|
value: token,
|
|
@@ -325,6 +331,23 @@ module Clowk
|
|
|
325
331
|
})
|
|
326
332
|
end
|
|
327
333
|
|
|
334
|
+
# A session written under :session still carries the token, and
|
|
335
|
+
# persist_clowk_session does not run again while that session stands — so
|
|
336
|
+
# without this, switching an app to :cookie would shrink nothing until every
|
|
337
|
+
# person signed out and back in. Drops the copy once, on the first request
|
|
338
|
+
# after the switch.
|
|
339
|
+
def drop_mirrored_token!
|
|
340
|
+
return unless Clowk.config.token_store == :cookie
|
|
341
|
+
|
|
342
|
+
store = clowk_session_store
|
|
343
|
+
held = stored_session
|
|
344
|
+
|
|
345
|
+
return if store.nil? || held.nil?
|
|
346
|
+
return unless held.key?("token") || held.key?(:token)
|
|
347
|
+
|
|
348
|
+
store[Clowk.config.session_key] = held.except("token", :token)
|
|
349
|
+
end
|
|
350
|
+
|
|
328
351
|
def resolve_session_status(force: false)
|
|
329
352
|
@clowk_session_check_unavailable = false
|
|
330
353
|
cached = force ? nil : clowk_read_cached_session_status
|
data/lib/clowk/configuration.rb
CHANGED
|
@@ -27,6 +27,7 @@ module Clowk
|
|
|
27
27
|
attr_accessor :session_status_ttl
|
|
28
28
|
attr_accessor :max_session_age
|
|
29
29
|
attr_accessor :fail_open_on_broker_error
|
|
30
|
+
attr_accessor :token_store
|
|
30
31
|
attr_writer :session_status_cache
|
|
31
32
|
|
|
32
33
|
def initialize
|
|
@@ -64,6 +65,25 @@ module Clowk
|
|
|
64
65
|
# cannot be made at all, the session is left standing and checked again on
|
|
65
66
|
# the next request; max_session_age is what bounds that.
|
|
66
67
|
@fail_open_on_broker_error = true
|
|
68
|
+
|
|
69
|
+
# Where the token is kept for the next request: :session or :cookie.
|
|
70
|
+
#
|
|
71
|
+
# Clowk's own cookie is written either way — it is what `current_token`
|
|
72
|
+
# reads when the session has none, and the only place an API-only app has
|
|
73
|
+
# ever had. The setting decides whether a COPY is also mirrored into the
|
|
74
|
+
# app's Rails session, as every version before 0.9 did.
|
|
75
|
+
#
|
|
76
|
+
# That copy is not free. A Rails session lives in ONE cookie with about
|
|
77
|
+
# 4096 bytes to its name, and in production, where tokens are RS256, the
|
|
78
|
+
# token is most of what a session weighs. Hand a browser more than it will
|
|
79
|
+
# hold and it discards the whole cookie in silence: no error server-side,
|
|
80
|
+
# none in the console, the previous cookie simply stays. Everything written
|
|
81
|
+
# on that request goes with it — a flash message, a selected tenant — which
|
|
82
|
+
# reads as a button that does nothing.
|
|
83
|
+
#
|
|
84
|
+
# :session stays the default so an upgrade changes nothing until an app
|
|
85
|
+
# asks for :cookie.
|
|
86
|
+
@token_store = :session
|
|
67
87
|
end
|
|
68
88
|
|
|
69
89
|
# Where API-only apps cache session status, since they have no Rails session
|
data/lib/clowk/version.rb
CHANGED