Stateless, signed challenge tokens.
A token carries a version, the difficulty, when it was issued and when it
expires, and a random salt, followed by a truncated HMAC-SHA256 over those
fields and the client identity (see Limen.Challenge.binding/1). The
identity is not stored in the token, so a token solved by one client is
useless to any other.
<<version, difficulty, issued_at::32, expires_at::32, salt::8 bytes, mac::16 bytes>>It is sent URL-safe base64 encoded, 46 characters.
Summary
Functions
Issues a token for the client in ctx.
Whether nonce solves token at difficulty: SHA-256(token <> nonce)
starts with at least difficulty zero bits.
Verifies a token presented by the client in ctx.
Types
@type claims() :: %{ difficulty: pos_integer(), issued_at: non_neg_integer(), expires_at: non_neg_integer(), mac: binary() }
Functions
@spec issue(Limen.Context.t(), pos_integer()) :: String.t()
Issues a token for the client in ctx.
@spec solved?(String.t(), String.t(), pos_integer()) :: boolean()
Whether nonce solves token at difficulty: SHA-256(token <> nonce)
starts with at least difficulty zero bits.
Nonces are decimal strings of at most 20 digits.
@spec verify(String.t(), Limen.Context.t()) :: {:ok, claims()} | {:error, :malformed | :invalid | :expired}
Verifies a token presented by the client in ctx.