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:
- HMAC-signatur (först) – Validerar att begäran kommer från en betrodd källa (webbplatsen)
- 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-routenbootstrap/app.php- Registreradehmac-middleware-aliasapp/Models/ApiKey.php- Lade till fältethmac_secret(hemligheter per användare)app/Http/Controllers/DashboardController.php- Genererar HMAC-hemlighet vid skapande av API-nyckeldatabase/migrations/2026_08_03_214931_add_hmac_secret_to_api_keys_table.php- Migrering för kolumnen hmac_secretresources/js/Pages/Dashboard/ApiKeys.svelte- Visar HMAC-hemlighet för användaren (en gång)docs/hmac-signature-guide.md- Implementeringsguide för klienttests/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):
openssl rand -hex 32
Databasschema
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)
// 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:
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
- Exponera aldrig hemligheten i klientkod – signera endast på servern
- Använd HTTPS – HMAC skyddar mot obehöriga förfrågningar, HTTPS skyddar mot MITM
- Rotera hemligheter regelbundet – särskilt om de komprometterats (kräver att API-nyckeln återskapas)
- Övervaka misslyckade signaturer – upprepade misslyckanden kan tyda på attacker
- Isolering per användare – varje API-nyckel har sin egen HMAC-hemlighet, en komprometterad nyckel påverkar inte andra
Referenser
- HMAC-signaturguide för klienter
- Snabbstartsguide
- OWASP: Fuskblad för kryptografisk lagring
- PHP: hash_hmac()