Ämne

HMAC-validering

HMAC-validering är hur FastOG verifierar att varje prenumerationsbaserad OG-bildförfrågan kommer från din egen server — signerade URL:er skyddar dina krediter. Registrera dig, välj sedan en Dynamic API-plan och skapa din API-nyckel och HMAC-hemlighet i instrumentpanelen (dashboard); betalda API-renderingar är rena. Den här sidan täcker de serverbaserade reglerna bakom dynamiska Open Graph-bilder, från kanonisk frågesignering till jämförelse i konstant tid.

Översikt

HMAC-SHA256-signaturvalidering har lagts till i /api/v1/og-slutpunkten för att förhindra obehörig användning av API-kvoten. Detta säkerställer att endast förfrågningar från den legitima webbplatsen kan generera OG-bilder.

Arkitektur

Tvålager-autentisering:

  1. HMAC-signatur (först) – Validerar att begäran kommer från en betrodd källa (webbplatsen)
  2. API-nyckel (andra) – Identifierar användarkontot för kvotredovisning av renderingar

En enda middleware (ApiKeyAuth): verifierar signaturen (query-parametrar) och löser API-nyckeln för kvotredovisning av renderingar i ett steg – misslyckas snabbt vid felaktiga signaturer.

Query-parametrar, inte headers: Eftersom OG-bilder hämtas av crawlers från sociala nätverk (LinkedIn, Twitter, Facebook) som inte skickar anpassade headers, skickas signaturen i webbadressens query-parametrar:

GET /api/v1/og?title=Hello&key=sk_quick_123abc&s=<hmac>

Implementering

Skapade/ändrade filer

  • app/Http/Middleware/HmacSignature.php - Ny middleware som validerar HMAC-signaturer (query-parametrar)
  • routes/api.php - Lade till HMAC-middleware i OG-routen
  • bootstrap/app.php - Registrerade hmac-middleware-alias
  • app/Models/ApiKey.php - Lade till fältet hmac_secret (hemligheter per användare)
  • app/Http/Controllers/DashboardController.php - Genererar HMAC-hemlighet vid skapande av API-nyckel
  • database/migrations/2026_08_03_214931_add_hmac_secret_to_api_keys_table.php - Migrering för kolumnen hmac_secret
  • resources/js/Pages/Dashboard/ApiKeys.svelte - Visar HMAC-hemlighet för användaren (en gång)
  • docs/hmac-signature-guide.md - Implementeringsguide för klient
  • tests/Feature/HmacSignatureTest.php - 8 godkända tester

Signaturalgoritm

method = HTTP method (e.g., "GET")
path  = request path (e.g., "/api/v1/og")
query = the request's DECODED query params

canonical = every param except `s`, keys sorted (array values sorted too),
            each `key=value` RFC-3986 encoded (unreserved-only), joined with "&"
message   = method + "/" + path + "\n" + canonical
signature = HMAC-SHA256(message, hmac_secret)

Query parameters:
  key=<apiKey>
  s=<signature>
  (no timestamp)

key ingår i den kanoniska query-strängen, så signaturen är bunden till API-nyckeln. Om någon parameter ändras (title, template, image, …) eller själva nyckeln ändras, ändras den kanoniska strängen → signaturmatchning misslyckas → 401 → ingen rendering, ingen kvoträkning. Identiska parametrar → identisk signatur → identisk URL → cachbar vid kanten för alltid, kan spelas upp utan att räknas.

Säkerhetsfunktioner

  • Innehållsadresserad signatur - Alla parameterändringar → 401 → ingen rendering, ingen kvoträkning (URL:en är själva beviset)
  • Ingen tidsstämpel - URL:er bäddas in i offentlig HTML och cachas för alltid; de måste överleva längre än 5 minuter
  • Jämförelse i konstant tid (hash_equals()) - Förhindrar timingattacker
  • API-nyckel i meddelandet - Signaturen är bunden till nyckeln; om nyckeln byts ut misslyckas det
  • Sökvägsspecifik - Signaturen gäller endast för exakt sökväg
  • Metodspecifik - En GET-signatur fungerar inte för POST
  • Hemligheter per användare - Varje API-nyckel har sin egen HMAC-hemlighet, kan återkallas oberoende (rotation = kill switch för läckta URL:er)

Konfiguration

Generera hemlighet (automatiskt)

HMAC-hemligheten genereras automatiskt när du skapar en API-nyckel i instrumentpanelen. Den visas en gång tillsammans med API-nyckeln och visas sedan aldrig igen.

Manuell generering (om det behövs):

bash
openssl rand -hex 32

Databasschema

sql
ALTER TABLE api_keys ADD COLUMN hmac_secret VARCHAR(64)
  COMMENT 'HMAC-SHA256 secret for signing OG image URLs (hex, 64 chars)';

Miljövariabler

Ingen global miljövariabel behövs – hemligheter lagras per användare i tabellen api_keys.

Användningsexempel (webbplatsens backend)

javascript
// Node.js example - generate signed OG image URL
const crypto = require("crypto");

// RFC-3986 encode (encodeURIComponent leaves !'()* unencoded).
const enc = (s) =>
    encodeURIComponent(s).replace(
        /[!'()*]/g,
        (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase(),
    );

function generateOgImageUrl(baseUrl, params, apiKey, hmacSecret) {
    const all = { ...params, key: apiKey };

    // Canonical: every param (except s), sorted, RFC-3986 encoded, joined with "&".
    const pairs = [];
    for (const [k, v] of Object.entries(all)) {
        for (const vv of Array.isArray(v) ? [...v].sort() : [v])
            pairs.push(`${enc(k)}=${enc(vv)}`);
    }
    pairs.sort();
    const canonical = pairs.join("&");

    const message = `GET/api/v1/og\n${canonical}`;
    const signature = crypto
        .createHmac("sha256", hmacSecret)
        .update(message)
        .digest("hex");

    const url = new URL(baseUrl);
    for (const [k, v] of Object.entries(all)) {
        const isArray = Array.isArray(v);
        for (const vv of isArray ? v : [v])
            url.searchParams.append(isArray ? `${k}[]` : k, vv);
    }
    url.searchParams.set("s", signature);
    return url.toString();
}

// Usage in meta tag
const ogUrl = generateOgImageUrl(
    "https://fastog.com/api/v1/og",
    { title: "Como criar um SaaS", template: "blog" },
    "sk_quick_123abc",
    process.env.HMAC_SECRET,
);

// <meta property="og:image" content="{ogUrl}" />

Felsvar

Status Kod Beskrivning
401 missing_signature Saknad key- eller s-frågeparameter
401 invalid_signature Signaturen matchar inte den kanoniska frågan (manipulerad eller fel hemlighet)

Testning

Kör testerna:

bash
php artisan test --filter HmacSignatureTest

Alla 8 tester passerar:

  • ✅ Begäran utan signatur avvisas
  • ✅ Begäran med saknad nyckelparameter avvisas
  • ✅ Manipulerad innehållsparameter (titel ändrad) avvisas
  • ✅ Tillagd parameter avvisas
  • ✅ Ogiltig signatur avvisas
  • ✅ Giltig signatur klarar HMAC-kontrollen
  • ✅ Signatur är sökvägsspecifik
  • ✅ Signatur är metodspecifik
  • ✅ Olika API-nycklar har olika hemligheter

Prestandapåverkan

  • Försumbar – HMAC-SHA256-beräkning tar ~0,1 ms per begäran
  • Inga extra nätverksanrop – Valideringen sker lokalt
  • Snabbt avbrott – Ogiltiga signaturer avvisas innan API-nyckelslagning

Säkerhetsöverväganden

  1. Exponera aldrig hemligheten i klientkod – signera endast på servern
  2. Använd HTTPS – HMAC skyddar mot obehöriga förfrågningar, HTTPS skyddar mot MITM
  3. Rotera hemligheter regelbundet – särskilt om de komprometterats (kräver att API-nyckeln återskapas)
  4. Övervaka misslyckade signaturer – upprepade misslyckanden kan tyda på attacker
  5. Isolering per användare – varje API-nyckel har sin egen HMAC-hemlighet, en komprometterad nyckel påverkar inte andra

Referenser

Fullständig API-referens

Prova gratis – ingen registrering krävs

Förhandsgranska och testa dynamiska OG-bilder på några sekunder.

Öppna gratis OG-bildtestaren

A BeCaSimulations site