pub fn generate_hmac_token_ctx(
class: TokenClass,
id: &str,
secret: &[u8],
) -> StringExpand description
Generates an HMAC-protected CSRF token bound to a context and identifier.
The produced token has the shape HEX_HMAC.RANDOM, where:
RANDOMis a fresh value fromgenerate_random_token.HEX_HMACis a hex-encoded HMAC-SHA256 over the message"{class}|{id}|{RANDOM}", using the providedsecret.
This format is designed for the Double-Submit Cookie pattern:
- The server sets the token as a cookie and expects clients to echo it back via a form field or header.
- On receipt, the server recomputes the HMAC with the same
class,id, andsecret. If the HMAC matches, the token is authentic and not forgeable by the client.
The class determines which logical bucket the token belongs to:
TokenClass::Authorized: token that is bound to an authenticated session.TokenClass::Anonymous: token used before authentication (pre-session).
§Parameters
class: Distinguishes the token namespace (authorized vs. anonymous).id: Identifier bound into the token (e.g., a session id); must be the same value used later for verification.secret: Application-wide secret key (>= 32 bytes recommended). Changing the secret invalidates all existing tokens immediately.
§Security
- Tokens are unforgeable without knowledge of
secretandid. - Use different
classvalues to prevent confusion between anonymous and authorized tokens; they are not interchangeable. - Choose a high-entropy
secretwith at least 32 bytes.
§Examples
Generate and verify an authorized token.
use actix_csrf_middleware::{generate_hmac_token_ctx, validate_hmac_token_ctx, TokenClass};
let session_id = "user-session-id";
let secret = b"an-application-wide-secret-at-least-32-bytes!";
let tok = generate_hmac_token_ctx(TokenClass::Authorized, session_id, secret);
assert!(tok.contains('.'));
assert!(validate_hmac_token_ctx(TokenClass::Authorized, session_id, tok.as_bytes(), secret).unwrap());Generate an anonymous token (pre-session) and verify it with the same id and class.
use actix_csrf_middleware::{generate_hmac_token_ctx, validate_hmac_token_ctx, TokenClass};
let pre_session_id = "pre-session";
let secret = b"an-application-wide-secret-at-least-32-bytes!";
let tok = generate_hmac_token_ctx(TokenClass::Anonymous, pre_session_id, secret);
assert!(validate_hmac_token_ctx(TokenClass::Anonymous, pre_session_id, tok.as_bytes(), secret).unwrap());