Verify results

While the client can trust the authenticity of the received data, a remote service must not assume that the client will forward it unchanged. To ensure trust in data from untrusted sources, your services must always verify its signature.

All service results are authenticated with an HMAC, include a timestamp, and carry the your ticket identifier. To validate the results, your backend needs to verify the HMAC of the result data and ensure the ticket identifier matches the expected value. Usually, a JWT library for your backend can help with this verification process.

Verifying results in your backend:

  • Python

  • Java

  • Rust

  • PHP

import jwt

result = jwt.decode(token, HMAC_KEY, algorithms=["HS256"])

assert result["data"]["ticket_id"] == issued_ticket_id
Jws<Claims> jwsClaims = Jwts.parserBuilder()
    .setSigningKey(Keys.hmacShaKeyFor(HMAC_KEY))
    .build()
    .parseClaimsJws(token);

@SuppressWarning("unchecked")
Map<String, Object> data = (Map<String, Object>) jwsClaims.getPayload().get("data");

assert data.get("ticket_id").equals(issuedTicketId)
let result = jsonwebtoken::decode::<serde_json::Value>(
    token,
    &jsonwebtoken::DecodingKey::from_secret(HMAC_KEY),
    &jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256),
)?;

assert_eq!(
    result.claims.get("data")?.get("ticketId")?,
    issued_ticket_id
);
$result = Firebase\JWT\JWT::decode(
    $token,
    new Firebase\JWT\Key($HMAC_KEY, 'HS256')
);

if ($result->data->ticketId != $issuedTicketId)
    throw new Exception("Unexpected ticket ID");