Class: TrackRelay::ClientId::SignedToken
- Inherits:
-
Object
- Object
- TrackRelay::ClientId::SignedToken
- Defined in:
- lib/track_relay/client_id/signed_token.rb
Overview
First-party, HMAC-signed client token — the spoof-proof
replacement for _ga-cookie browser proof.
The cookie value is generated and verified with
ActiveSupport::MessageVerifier (SHA256), so any tampering,
truncation, or wrong-secret forgery verifies to nil rather
than raising.
Defined Under Namespace
Classes: Token
Constant Summary collapse
- COOKIE_NAME =
"_tr_cid"
Class Method Summary collapse
-
.from_request(request, secret:) ⇒ String?
Convenience for gate/client-id use: just the verified client_id.
-
.mint(secret:, client_id:, session_id: nil, session_started_at: nil, last_seen_at: nil, ttl: nil) ⇒ String
Generate a signed cookie value embedding the client_id and optional session fields.
-
.read(request, secret:) ⇒ Token?
Read and verify the signed cookie into a Token.
Class Method Details
.from_request(request, secret:) ⇒ String?
Convenience for gate/client-id use: just the verified client_id.
70 71 72 |
# File 'lib/track_relay/client_id/signed_token.rb', line 70 def self.from_request(request, secret:) read(request, secret: secret)&.client_id end |
.mint(secret:, client_id:, session_id: nil, session_started_at: nil, last_seen_at: nil, ttl: nil) ⇒ String
Generate a signed cookie value embedding the client_id and optional session fields.
31 32 33 34 35 36 37 38 39 |
# File 'lib/track_relay/client_id/signed_token.rb', line 31 def self.mint(secret:, client_id:, session_id: nil, session_started_at: nil, last_seen_at: nil, ttl: nil) payload = { "cid" => client_id, "sid" => session_id, "sst" => session_started_at&.to_i, "lsa" => last_seen_at&.to_i }.compact verifier(secret).generate(payload, expires_in: ttl) end |
.read(request, secret:) ⇒ Token?
Read and verify the signed cookie into a Token.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/track_relay/client_id/signed_token.rb', line 48 def self.read(request, secret:) value = request&.&.[](COOKIE_NAME) return nil if value.nil? || value.empty? payload = verifier(secret).verified(value) return nil unless payload Token.new( client_id: payload["cid"], session_id: payload["sid"], session_started_at: payload["sst"] && Time.at(payload["sst"]).utc, last_seen_at: payload["lsa"] && Time.at(payload["lsa"]).utc ) end |