Hitelesítés
Jogosultságok, az app telepítése, hívás appként vagy egy személy nevében, valamint session JWT-k.
Ezen az oldalon
| Hitelesítési adat | Birtokos | Használat |
|---|---|---|
| App hozzáférési token | A te szervered | PolturaClient bearer az App API-hoz (/apps-api/v1), Poltura-Installation headerrel |
| Kereskedői session JWT | RAM egyetlen kérés erejéig | Igazolja, hogy melyik kereskedő tekint meg egy hosztolt iframe-et. Nem API-bearer. JWT-típus: poltura-app-session+jwt, 60 másodpercig érvényes, legfeljebb 4096 bájt |
Jogosultságok
Az app jogosultság-azonosítókat kér: pontosan azokat a jogosultságokat, amelyeket a kereskedők adnak a csapattagjaiknak. A kereskedő által megadott jogosultságok az installation.retrieve().permissions mezőben találhatók. A kötelező jogosultságok mindig szerepelnek benne; a kereskedő által elutasított opcionális jogosultságok hiányoznak. Egy olyan hívás, amelyhez az appnak nincs meg a szükséges jogosultsága, 403 forbidden hibával meghiúsul: az újrapróbálkozás helyett tájékoztasd a kereskedőt arról, hogy a funkció melyik jogosultságot igényli. Az App API ezeket használja:
| Jogosultság | App API-hozzáférés |
|---|---|
settings.read | GET /store: a bolt neve, nyelve (locale), pénzneme és nyilvános képességei. |
products.read | Termékek, gyűjtemények és készletszintek. |
products.write | Termékcím, leírás, handle, állapot és metaadatok; gyűjtemény címe, handle-je és metaadatai. Árak és készlet nem. |
orders.read | Rendelés állapota, végösszegek, tételek és szállítási cím. |
orders.write | Rendelés metaadatai, címkék és megjegyzés. Állapot, fizetés vagy teljesítés nem. |
customers.read | Vásárló neve, e-mail-címe, telefonszáma, címkéi és metaadatai. |
customers.write | Vásárló metaadatai és címkéi. Fiók állapota nem. |
A GET /installation endpointhoz és a telepítés tárhelyéhez (installation storage) nincs szükség jogosultságra: a tárhely a telepítés saját adatait tárolja, nem a kereskedőét. Minden jogosultság, amelyet egy app kérhet, a Jogosultságok és témakörök oldalon található, a teljes katalógus pedig címkékkel és leírásokkal a GET https://api.poltura.com/v1/access/catalog?locale=en (vagy locale=hu) végponton érhető el. A manifestben az egyes jogosultságokhoz tartozó purpose mező 8–280 karakter hosszú, és ezt látja a kereskedő.
Hitelesítési adatok
A Developer apps → Credentials menüpontban regisztrálj egy vagy több saját nyilvános kulcsot (RSA 2048+ RS256-tal, vagy EC P-256 ES256-tal) JWKS formátumban. A privát kulcsok soha nem hagyják el a szervereidet. A Poltura ID a következőkkel válaszol:
- az app client id-ja azokhoz a hívásokhoz, amelyeket egy személy hajt végre az appodon keresztül;
- az app gépi felhasználói azonosítója (machine user id) és – minden kulcshoz – a key id, amelyet a JWT profile claimjeid megneveznek.
A key rotationhöz regisztráld az új kulcsot a régi mellé, élesítsd a módosítást, majd távolítsd el a régit.
Telepítés
A kereskedő a https://id.poltura.com/install?app=<app id> címen telepíti az appodat a Poltura ID-ban. Helyezz el ide mutató linket az onboarding folyamatodban. A telepítésre jogosult személy kiválasztja a boltokat (egy listát, vagy minden boltot, beleértve a jövőbelieket is), látja a céljaiddal zárolt kötelező jogosultságokat, és bekapcsolja az opcionálisakat. Senki sem adhat több jogosultságot az appodnak, mint amivel saját maga rendelkezik. A telepítéshez ezután boltonként egy telepítési azonosító (installation id) tartozik (egy UUID, például 0199f3c4-2a6e-7f81-b3d5-6e7f8091a2b3); az app.installed esemény és a GET /installation endpoint megmondja, melyik az.
Hívás az appodként
A szervered magának az appnak a nevében jár el a JWT profile (RFC 7523) segítségével: aláír egy claimet a gépi felhasználója számára, és beváltja a https://id.poltura.com/oauth/v2/token címen. Minden App API-hívás megnevezi a bolt telepítését a Poltura-Installation headerben; a hozzáférést a telepítés jogosultságai döntik el.
import { PolturaClient } from '@poltura/app-sdk';
import { createAppTokenSource } from '@poltura/app-sdk/oauth';
const tokens = createAppTokenSource({
issuer: 'https://id.poltura.com',
userId: process.env.POLTURA_MACHINE_USER_ID,
keyId: process.env.POLTURA_KEY_ID,
privateKey: privateJwk,
});
const client = new PolturaClient({
origin: 'https://api.poltura.com',
accessToken: await tokens.accessToken(),
installationId: '0199f3c4-2a6e-7f81-b3d5-6e7f8091a2b3',
});Hívás egy személy nevében
Ha az appodat használó személy nevében szeretnél eljárni, futtasd az engedélyezési kódos folyamatot (authorization code flow) PKCE-vel a Poltura ID felé a createPublicAppOAuthClient segítségével, saját kulcsoddal hitelesítve (private_key_jwt). Kérd a szükséges jogosultság-azonosítókat a manifested kötelező és opcionális jogosultságai közül. A személy a Poltura ID-ban adja meg a hozzájárulást. Egy ilyen hívás csak azt teheti meg, amit a telepítés, a személy hozzájárulása és a személy aktuális szerepköre együttesen megenged, a bolt naplója pedig a te appodon keresztül nevezi meg a személyt.
Elutasítások és változások
- Az
error.code: "insufficient_scope"értékkel érkező403hiba megnevezi azt a jogosultságot (permission), amelyre a hívásnak szüksége lett volna. Ha egy személy hozzájárulásából hiányzik egy olyan jogosultság, amellyel a telepítés rendelkezik, aWWW-Authenticatefelsorolja az újra kérendő jogosultságot; bármi, amivel a telepítés nem rendelkezik, a kereskedő jóváhagyására vár. - Az a release, amely kötelező jogosultságokat ad hozzá, azonnal élesedik; a telepítés megőrzi a korábban megadott jogosultságait mindaddig, amíg egy adminisztrátor jóvá nem hagyja az újakat a Poltura ID-ban. A release-ből eltávolított jogosultságok azonnal megszűnnek. Az opcionális jogosultságokra a rendszer soha nem kérdez rá; ezeket egy személytől kérd el hozzájáruláson keresztül.
- Az
installation.permissions_changedés azinstallation.stores_changedesemények jelzik, hogy újra le kell kérdezned aGET /installationendpointot: ez visszaadja a boltokat, az adott hívás által használható jogosultságokat és a függőben lévőket. - Az eltávolítás visszavonja a telepítést és minden olyan hozzájárulást, amelyet egy személy adott az appodnak az adott szervezetben; a régi tokenek működése azonnal megszűnik.
Session tokenek hosztolt oldalakhoz
A hosztolt oldalak egy iframe-ben futnak az adminfelületen. Amikor az oldal meghívja a szerveredet, a szerverednek tudnia kell, hogy melyik kereskedővel és melyik telepítéssel kommunikál. Ezt egy cookie nem tudja közölni: az oldal a te kiszolgálódon található a Polturáén belül, a böngészők pedig blokkolják az ilyen cookie-kat. Az oldal ezért egy session tokent kér az adminfelülettől, és ezt küldi el minden kéréssel.
A session token egy aláírt igazolás a Polturától: ennél a kereskedőnél éppen nyitva van ennek az appnak ez a telepítése. Legfeljebb 60 másodpercig érvényes, nem tartalmaz jogosultságokat, és nem API token: az App API elutasítja. A szervered kizárólag arra használja, hogy kiválassza a tárolt telepítési tokent.
- Add hozzá a
get_session_tokenműveletet azadminFrame.actionslistához a manifestben. - Az oldalon csatlakozz az adminfelülethez, és kérj egy tokent. Az SDK csak a memóriában tartja:
const session = connectAppFrame({
window,
parentWindow: window.parent,
parentOrigin: root.dataset.parentOrigin ?? '',
approvedFrameOrigin: root.dataset.frameOrigin ?? '',
actions: ['get_session_token'],
});
try {
await ready(session);
const { token } = await requestAppSession(session);
const response = await fetch('/api/overview', {
headers: { authorization: `Bearer ${token}` },
credentials: 'omit',
});A parentOrigin a Poltura adminfelületének címe, az approvedFrameOrigin pedig a sajátod; a példában szereplő szerver mindkettőt beírja az oldalba. A requestAppSession AppFrameSessionError hibát dob, mielőtt az adminfelület csatlakozott volna, ha a manifest nem sorolja fel a get_session_token műveletet, vagy miután a keret megszűnt.
- A szervereden hozz létre egy ellenőrzőt indításkor:
const sessions = createAppSessionVerifier({
issuer: env.POLTURA_SESSION_ISSUER,
audience: appOrigin,
appId: env.POLTURA_CLIENT_ID,
jwks: JSON.parse(env.POLTURA_SESSION_JWKS),
oauthIssuer: env.POLTURA_ISSUER,
apiAudience: env.POLTURA_RESOURCE,
merchantIssuer: env.POLTURA_MERCHANT_ISSUER,
});Az audience az oldalad címe. A jwks a session issuer nyilvános kulcskészlete; az SDK magától soha nem kér le kulcsokat, ezért töltsd be újra, amikor a Poltura új kulcsot ad hozzá. Az oauthIssuer, az apiAudience és a merchantIssuer értékeket kötelező megadni, és mindegyiknek különböznie kell egymástól, valamint a session issuerétől is, hogy az egyikhez szánt tokent ne lehessen elfogadni egy másikként.
- Ellenőrizz minden kérést, majd párosítsd a telepítéskor eltárolt telepítéssel:
const header = req.headers.authorization ?? '';
const token = header.startsWith('Bearer ') ? header.slice('Bearer '.length) : '';
const session = await sessions.verify(token);
const connection = connections.get(session.installationId);
const bound =
connection !== undefined &&
connection.installation.appId === session.appId &&
connection.installation.storeId === session.storeId &&
connection.installation.releaseId === session.releaseId &&
connection.installation.generation === session.generation;
const reconnect = { connectUrl: `${appOrigin}/connect?installation=${session.installationId}` };
if (connection === undefined || !bound) {
json(res, 409, reconnect);
return;
}A verify ellenőrzi az ES256 aláírást, a poltura-app-session+jwt típust, az issuert, az audience-t, az appazonosítódat és a legfeljebb 60 másodperces élettartamot (5 másodperces óraeltéréssel), továbbá elutasítja a 4096 bájtnál nagyobb tokeneket. Bármilyen hiba esetén AppSessionError kivételt dob részletek nélkül. Siker esetén visszaadja a kereskedőt (subject), valamint az appId, storeId, installationId, releaseId, generation, revision, manifestDigest, frameId, jti értékeket és a timestampeket.
- Az érvényes aláírás azt jelzi, hogy a kereskedőnél nyitva volt az oldal; nem bizonyítja, hogy a telepítés még mindig aktív. Bármilyen érzékeny művelet előtt hívd meg az App API-t a tárolt tokennel, ami meghiúsul, ha az appot időközben eltávolították.
- Egy token a lejáratáig újra elküldhető. Ha egy műveletnek pontosan egyszer kell lefutnia, rögzítsd a hozzá tartozó
jtiértéket. - Ha még nincs tárolt telepítésed, az oldal ezt nem tudja megoldani az iframe-ből: nem tud felugró ablakokat nyitni, és nem tud navigálni az adminfelületen sem. A példa
409-es választ ad a csatlakozási címmel, az oldal pedig megkéri a kereskedőt, hogy nyissa meg azt egy új lapon.
Aláírt műveletek
A natív worker egy műveleten keresztül hívja meg a szerveredet: a workerben kiadott useAction('suggest_box') egy POST kéréssé válik a backendOrigin és a művelet útvonalának kombinációjára, amelyet a Poltura ír alá. Ellenőrizd a @poltura/app-sdk/actions csomagból származó createActionHandler segítségével:
const actions = createActionHandler({
trustedKeys: [{ kid: env.POLTURA_WEBHOOK_KID, publicKeyPem: env.POLTURA_WEBHOOK_PUBLIC_KEY }],
handlers: {
suggest_box(request) {
return suggestBox(SuggestBoxInput.parse(request.input).quantity);
},
check_listing(request) {
return { hints: listingHints(CheckListingInput.parse(request.input)) };
},
},
});Az actions.handle(rawBody, headers) ellenőrzi a kérést, lefuttatja a kérés által megnevezett handlert, és visszaadja annak JSON-válaszát. A request bodyt pontosan úgy add át bájtokként, ahogyan megérkezett; az előzetes parszolás érvényteleníti az aláírást.
| Header | Jelentés |
|---|---|
poltura-signature | v1= és egy Ed25519 aláírás, kitöltés nélküli base64url formátumban a <timestamp>.<raw body> felett |
poltura-timestamp | Unix másodperc, amikor a Poltura aláírta a kérést |
poltura-action | A művelet azonosítója; kiválasztja a handlert |
poltura-installation, poltura-store | A telepítés és a bolt; egyezniük kell a request bodyval |
poltura-surface | admin vagy storefront; egyeznie kell a request bodyval |
poltura-request-id | A hívás egyedi azonosítója |
poltura-shopper | Webáruházi hívásoknál van jelen |
A request body mérete legfeljebb 64 KiB, szerkezete: { "input": ..., "context": { "installationId", "storeId", "surface", "locale", "instanceId", ... } }. A request.input bármi lehet, amit a worker átadott; validáld úgy, mint bármely más bemenetet.
- A 300 másodpercnél régebbi vagy ennyivel a jövőbe mutató timestampeket a rendszer elutasítja (
expired_timestamp,future_timestamp). - Az ezen az időablakon belüli replayek érvényes aláírással rendelkeznek. Ha egy művelet módosít valamit, tárold el a
poltura-request-idértékét, és hagyd figyelmen kívül az ugyanazzal az azonosítóval érkező második kérést. - Kulcsok: a műveletek ugyanazzal a platformkulccsal vannak aláírva, mint a webhookok. Adj meg 1–8 nyilvános kulcsot; a key rotation során bízz meg a régiben és az újban is.
- A hibák
PolturaActionErrortípusúak, a következő hibakódokkal (code):invalid,wrong_algorithm,unknown_kid,expired_timestamp,future_timestamp,noncanonical_signature,payload_too_large,altered_bodyvagynot_declared(nincs kezelő az adott művelethez). Válaszolj rájuk4xxkóddal; a worker hívása ekkor meghiúsul.
Aláírt webhookok
A webhookok ugyanezt az aláírást használják: Ed25519 a <timestamp>.<raw body> felett, 300 másodperces időablak és a platform signing keyje, amelyet a poltura-key-id header választ ki. A @poltura/app-sdk/webhooks csomagban található createWebhookVerifier ellenőrzi őket, és képes egyetlen bolt és telepítés megkövetelésére is. A részletek, témakörök és újrapróbálkozások a Webhookok oldalon találhatók.
Amit a böngésző soha nem kap meg
- Hozzáférési és frissítési tokenek. Kizárólag a szervered birtokolja őket. Soha ne küldd el egyiket se workernek, hosztolt oldalnak vagy URL-ben, még egy blokkolt cookie megkerülése érdekében sem.
- A saját privát signing keyed és az engedélyezési állapot. A böngésző csak az átirányítási címet és egy olyan opaque cookie-t hordoz, amely a szervereden lévő állapotra mutat.
- A session tokenek egyetlen kérés erejéig maradnak az oldal memóriájában: nem kerülhetnek cookie-kba, a
localStorage-ba, URL-ekbe vagy logokba. - A workerek a fentiek egyikét sem kapják meg. A szerveredet műveleteken keresztül érik el, amelyeket a Poltura ír alá és küld el a nevükben, a bolt adatait pedig kizárólag a platform által biztosított hookokon keresztül olvassák.