HMAC-validointi
HMAC-validointi on tapa, jolla FastOG varmistaa, että jokainen tilauspohjainen OG-kuvapyyntö on peräisin omalta palvelimeltasi — allekirjoitetut URL-osoitteet pitävät krediittisi turvassa. Rekisteröidy, valitse Dynamic API -suunnitelma ja luo API-avaimesi sekä HMAC-salaisuutesi hallintapaneelissa (dashboard); maksulliset API-renderöinnit ovat puhtaita. Tämä sivu kattaa palvelinpuolen säännöt dynaamisten Open Graph -kuvien takana, kanonisesta kyselymerkkien allekirjoituksesta vakioaikaiseen vertailuun.
Yleiskatsaus
HMAC-SHA256-allekirjoituksen vahvistus on lisätty /api/v1/og-päätepisteeseen estämään API-kiintiön luvaton käyttö. Tämä varmistaa, että vain oikean verkkosivuston pyynnöt voivat luoda OG-kuvia.
Arkkitehtuuri
Kaksitasoinen todennus:
- HMAC-allekirjoitus (ensimmäinen) – varmistaa, että pyyntö on peräisin luotetusta lähteestä (verkkosivusto)
- API-avain (toinen) – tunnistaa käyttäjätilin renderöintikiintiön laskentaa varten
Yksi middleware (ApiKeyAuth): varmistaa allekirjoituksen (kyselyparametrit) ja selvittää API-avaimen renderöintikiintiön laskentaa varten yhdellä kertaa – epäonnistu nopeasti virheellisillä allekirjoituksilla.
Kyselyparametrit, ei otsikot: Koska sosiaalisten verkostojen hakurobotit (LinkedIn, Twitter, Facebook) hakevat OG-kuvia eivätkä lähetä mukautettuja otsikoita, allekirjoitus välitetään URL-kyselyparametreissa:
GET /api/v1/og?title=Hello&key=sk_quick_123abc&s=<hmac>
Toteutus
Luodut/muokatut tiedostot
app/Http/Middleware/HmacSignature.php- Uusi middleware, joka validoi HMAC-allekirjoitukset (kyselyparametrit)routes/api.php- Lisätty HMAC-middleware OG-reitillebootstrap/app.php- Rekisteröityhmac-middleware-aliasapp/Models/ApiKey.php- Lisättyhmac_secret-kenttä (käyttäjäkohtaiset salaisuudet)app/Http/Controllers/DashboardController.php- Luo HMAC-salaisuuden API-avaimen luonnin yhteydessädatabase/migrations/2026_08_03_214931_add_hmac_secret_to_api_keys_table.php- Migraatio hmac_secret-sarakkeelleresources/js/Pages/Dashboard/ApiKeys.svelte- Näyttää HMAC-salaisuuden käyttäjälle (kerran)docs/hmac-signature-guide.md- Asiakasohje toteutukseentests/Feature/HmacSignatureTest.php- 8 läpäisevää testiä
Allekirjoitusalgoritmi
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 on osa kanonista kyselyä, joten allekirjoitus on sidottu API-avaimeen. Minkä tahansa parametrin (otsikko, malli, kuva jne.) tai itse avaimen muuttaminen muuttaa kanonista merkkijonoa → allekirjoitus ei täsmää → 401 → ei renderöintiä, ei kiintiön kulutusta. Samat parametrit → sama allekirjoitus → sama URL → välimuistitettavissa reunalla pysyvästi, toistettavissa ilman laskutusta.
Tietoturvaominaisuudet
- Sisältöosoitteinen allekirjoitus - Mikä tahansa parametrimuutos → 401 → ei renderöintiä, ei kiintiön kulutusta (URL itsessään on todiste)
- Ei aikaleimaa - URLit upotetaan julkiseen HTML:ään ja välimuistitetaan pysyvästi; niiden on kestettävä yli 5 minuuttia
- Vakioaikainen vertailu (
hash_equals()) - Estää ajoituspohjaiset hyökkäykset - API-avain viestissä - Allekirjoitus on sidottu avaimeen; avaimen vaihto epäonnistuu
- Polkukohtainen - Allekirjoitus on voimassa vain tarkalle polulle
- Metodikohtainen - GET-allekirjoitus ei toimi POST-pyynnöissä
- Käyttäjäkohtaiset salaisuudet - Jokaisella API-avaimella on oma HMAC-salaisuutensa, joka voidaan peruuttaa itsenäisesti (kierto = hätäkatkaisin vuotaneille URLeille)
Konfiguraatio
Salaisen avaimen luominen (automaattinen)
HMAC-salainen avain luodaan automaattisesti, kun luot API-avaimen hallintapaneelissa (dashboard). Se näytetään kerran API-avaimen yhteydessä, eikä sitä näytetä sen jälkeen uudelleen.
Manuaalinen luominen (tarvittaessa):
openssl rand -hex 32
Tietokannan rakenne
ALTER TABLE api_keys ADD COLUMN hmac_secret VARCHAR(64)
COMMENT 'HMAC-SHA256 secret for signing OG image URLs (hex, 64 chars)';
Ympäristömuuttujat
Globaalia ympäristömuuttujaa ei tarvita – salaiset avaimet tallennetaan käyttäjäkohtaisesti api_keys-tauluun.
Käyttöesimerkki (verkkosivuston taustajärjestelmä)
// 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}" />
Virhevastaukset
| Tila | Koodi | Kuvaus |
|---|---|---|
| 401 | missing_signature |
Puuttuva key- tai s-kyselyparametri |
| 401 | invalid_signature |
Allekirjoitus ei vastaa kanonista kyselyä (muokattu tai väärä salaisuus) |
Testaaminen
Suorita testit:
php artisan test --filter HmacSignatureTest
Kaikki 8 testiä menevät läpi:
- ✅ Pyyntö ilman allekirjoitusta hylätään
- ✅ Pyyntö, josta puuttuu avainparametri, hylätään
- ✅ Muokattu sisältöparametri (otsikko muutettu) hylätään
- ✅ Lisätty parametri hylätään
- ✅ Virheellinen allekirjoitus hylätään
- ✅ Kelvollinen allekirjoitus läpäisee HMAC-tarkistuksen
- ✅ Allekirjoitus on polkukohtainen
- ✅ Allekirjoitus on metodikohtainen
- ✅ Eri API-avaimilla on eri salaisuudet
Suorituskykyvaikutus
- Vähäinen – HMAC-SHA256-laskenta vie noin 0,1 ms pyyntöä kohden
- Ei ylimääräisiä verkkokutsuja – vahvistus tapahtuu paikallisesti
- Epäonnistuu nopeasti – virheelliset allekirjoitukset hylätään ennen API-avaimen hakua
Tietoturvanäkökohdat
- Älä koskaan paljasta salaista avainta asiakaspuolen koodissa – Allekirjoita vain palvelimella
- Käytä HTTPS:ää – HMAC suojaa luvattomilta pyynnöiltä, HTTPS suojaa MITM-hyökkäyksiltä
- Vaihda salaiset avaimet säännöllisesti – Erityisesti jos ne ovat vaarantuneet (edellyttää API-avaimen uudelleengenerointia)
- Seuraa epäonnistuneita allekirjoituksia – Toistuvat epäonnistumiset voivat viitata hyökkäyksiin
- Käyttäjäkohtainen eristys – Jokaisella API-avaimella on oma HMAC-salaisuutensa, yhden vaarantuminen ei vaikuta muihin
Viitteet
- HMAC-allekirjoitusopas asiakkaille
- Pika-aloitusopas
- OWASP: Kryptografisen tallennuksen huijauslehti
- PHP: hash_hmac()