Skip to content

SignedReceiptCodec ​

Rasuvaeff\Yii3AbTestingWeb\SignedReceiptCodec

Class · rasuvaeff/yii3-ab-testing-web · Source

Encodes an AssignmentReceipt into a signed, transport-independent string, and decodes it back only if the signature holds.

Signing lived inside CookieAssignmentStore, tied to CookieSigner, which made it unusable anywhere a cookie is not the transport. A single-page application holds the receipt in localStorage and posts it back in a JSON body; without a signature the server has no way to tell a real receipt from a fabricated one, and a client could claim variant B while assigned A — corrupting the analytics rather than breaking anything visibly.

Re-resolving the assignment server-side is the alternative, but it answers a different question: after a reweight it returns the variant the visitor would get now, not the one they saw. That is precisely why receipts exist.

The signature covers the exact bytes that are decoded, so reordering or editing any field invalidates it.

Constructor ​

php
new SignedReceiptCodec(string $secret)
  • $secret — A private key, not a password: at least 32 bytes of entropy, never shared with the client, rotated by deploying a new value (which invalidates outstanding receipts).

Methods ​

encode() ​

php
encode(AssignmentReceipt $receipt): string

decode() ​

php
decode(string $value): ?AssignmentReceipt

Returns null for anything that is not a receipt this codec produced: missing, malformed, tampered with, or signed by a different secret. The caller treats that exactly like "no receipt" — a forged one must never be distinguishable from an absent one by its effect.