Node.js yönetim SDK'sı
@keenauth/node, KeenAuth yönetim API'si için TypeScript SDK'sıdır. Node.js 22 veya üzeri bir sürüm gerektirir ve çalışma zamanı bağımlılığı yoktur. Henüz npm'de yayımlanmamıştır.
Paketin şu giriş noktaları vardır:
| İçe aktarma | Kullanım amacı |
|---|---|
@keenauth/node |
Yönetim API istemcisi, yönetim token'ları, sayfalama ve hatalar |
@keenauth/node/webhooks |
API istemcisini yüklemeden webhook imzalarını doğrulama |
@keenauth/node/bff |
Sunucu uygulamaları için oturum açma: Express ve Fastify |
@keenauth/node/middleware |
Bearer token'larla API'nizi koruma |
@keenauth/node/testing |
Çevrimdışı test kiti |
İstemci oluşturma
Gizli veya kısıtlı bir API anahtarıyla:
import { KeenAuth } from "@keenauth/node";
const keenauth = new KeenAuth({
baseUrl: "https://api.eu.keenauth.com/v1",
apiKey: process.env.KEENAUTH_API_KEY!,
});
const user = await keenauth.users.getUser({ userId: "usr_01j9zzzzzzzzzzzzzzzzzzzz" });
baseUrl, bölgenizin API adresidir ve sonuna /v1 eklenir. https kullanmalıdır; düz http yalnızca localhost için kabul edilir. Anahtar yalnızca Authorization başlığında ve yalnızca bu adrese gönderilir. Yönlendirmeler takip edilmez.
API anahtarı olmadan kimlik doğrulama
management tipindeki bir uygulama, statik bir anahtar yerine kısa ömürlü bir token ile API'yi çağırabilir. Uygulama, özel anahtarıyla bir istemci onayı (assertion) imzalar (private_key_jwt, RFC 7523) ve SDK bunu ortamınızın token uç noktasında değiştirir.
- Panelde
managementtipinde bir uygulama ve ihtiyaç duyduğu izinlere sahip bir yönetim istemci kaydı oluşturun (bkz. Yönetim istemcisi oluşturma). - Bir anahtar çifti üretin ve genel anahtarı uygulamanın bir
public_keykimlik bilgisi olarak kaydedin. Örneğin ES256 için:openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out management-key.pem. - Özel anahtarı gizli bilgi deponuzda saklayın. SDK'ya iletin:
import { readFileSync } from "node:fs";
import { KeenAuth } from "@keenauth/node";
const keenauth = new KeenAuth({
baseUrl: "https://api.eu.keenauth.com/v1",
credentials: {
issuer: "https://acme.eu.keenauth.app", // ortamınızın issuer değeri, birebir
clientId: "app_01j9zzzzzzzzzzzzzzzzzzzz",
privateKey: readFileSync("management-key.pem", "utf8"), // PEM, özel JWK veya KeyObject
scope: ["users:read", "users:write"], // isteğe bağlı; varsayılan: uygulamanın varsayılan kapsamları
},
});
SDK şunları yapar:
<issuer>/oauth2/tokenadresinegrant_type=client_credentialsgönderir veresourcedeğerini yönetim API tanımlayıcısına ayarlar. Varsayılan,baseUrlkökenidir (örneğinhttps://api.eu.keenauth.com); değiştirmek içincredentials.audiencedeğerini ayarlayın.- Her istek için yeni bir istemci onayı üretilir:
issvesubistemci kimliğidir,audissuer'dır,jtirastgele bir değerdir ve onay 120 saniye geçerlidir.kidbaşlığı, anahtarın RFC 7638 parmak izidir; uygulamanın birden çok anahtarı olduğunda (anahtar rotasyonu için) KeenAuth anahtarı bu değerle bulur. - Algoritma anahtarı izler: RSA anahtarları
RS256ile imzalanır (RSA-PSS içinalg: "PS256"ayarlayın), P-256 anahtarlarıES256ile ve Ed25519 anahtarlarıEdDSAile imzalanır. RSA anahtarları en az 2048 bit olmalıdır. - Erişim token'ı önbelleğe alınır ve süresi dolmadan 60 saniye önce yenilenir. Eşzamanlı çağrılar tek bir yenilemeyi paylaşır. API
401yanıtı verirse önbellekteki token atılır ve bir sonraki çağrı yeni bir token alır.
Başarısız bir token isteği, OAuth code (örneğin invalid_client veya invalid_scope), description ve status ile birlikte TokenError fırlatır. Özel anahtar yerine genel anahtar verilmesi gibi bir yapılandırma hatası ise istemci oluşturulduğunda fırlatılır.
apiKey ve credentials birlikte kullanılamaz.
Yeniden deneme
API 429, 502, 503 veya 504 yanıtı verdiğinde ya da bağlantı kurulamadığında SDK bir isteği en fazla toplam 3 kez yeniden dener. Yalnızca GET, PUT ve DELETE istekleri ile bir Idempotency-Key taşıyan POST istekleri yeniden denenir. If-Match taşıyan bir PATCH yalnızca 429 yanıtında yeniden denenir: hız sınırlayıcı isteği çalışmadan reddeder ve If-Match, bir değişikliğin iki kez uygulanmasını önler. Diğer tüm PATCH istekleri hiçbir zaman yeniden denenmez.
- Yanıtta
Retry-Afterbaşlığı varsa (saniye veya HTTP tarihi), SDK o kadar süre bekler. 60 saniyeden uzun birRetry-Afterbeklenmez: SDK o yanıtı size döndürür. - Aksi halde önce 0,5 saniye, sonra 1 saniye beklenir; her beklemeye ±%25 rastgele jitter eklenir.
timeoutMs(varsayılan 30 saniye) yeniden denemeler dahil tüm çağrıyı sınırlar. Bir bekleme bu süreyi aşacaksa SDK bunun yerine son yanıtı döndürür.
SDK, desteklediği her POST işlemine rastgele bir Idempotency-Key ekler; böylece yeniden denenen bir oluşturma işlemi ikinci bir nesne oluşturmaz. Kendi yeniden denemelerinizi de güvenli kılmak için aynı anahtarı kendiniz iletebilirsiniz:
await keenauth.users.createUser({
userCreateRequest: { email: "ada@example.com" },
idempotencyKey: "signup-7d1f0c2a-0d7e-4c55",
});
Sayfalama
Listeleme uç noktaları tek bir sayfa döndürür: data ve before ile after imleçlerini içeren listMetadata. paginate, imleçleri sizin yerinize takip eder:
import { paginate } from "@keenauth/node";
for await (const user of paginate((p) => keenauth.users.listUsers(p), { limit: 100 })) {
console.log(user.id);
if (user.email === "ada@example.com") break; // bir sonraki sayfayı yüklemeden durur
}
beforeolmadanafterile ileriye doğru ilerler ve imleçnullolana kadar devam eder.beforeile geriye doğru ilerler.limit, sayfa boyutudur (1-100) ve her istekte gönderilir; diğer parametreler de korunur.paginatePages, öğeler yerine tam sayfalar verir.- Sunucu aynı imleci iki kez döndürürse döngü
PaginationErrorile durur.
Hatalar
Bir hata yanıtı, status, code, title, detail, requestId ve alan bazlı errors içeren bir ProblemError (RFC 9457) olur. İleti metnini değil, code değerini kontrol edin. SDK'nın tanımadığı kodlar dize olarak kullanılabilir kalır.
import { ProblemError } from "@keenauth/node";
try {
await keenauth.users.getUser({ userId });
} catch (e) {
if (e instanceof ProblemError && e.code === "not_found") {
// …
}
}
Bir proxy'den gelen HTML sayfası gibi, problem belgesi içermeyen bir yanıt ise ham response ile birlikte oluşturulmuş ResponseError olur.
Webhook'ları doğrulama
KeenAuth, webhook'ları Standard Webhooks v1 şemasıyla imzalar. İmzayı, isteği ayrıştırmadan önce ham istek gövdesiyle doğrulayın:
import express from "express";
import { Webhook, WebhookVerificationError } from "@keenauth/node/webhooks";
const webhook = new Webhook(process.env.KEENAUTH_WEBHOOK_SECRET!); // idp_whsec_…
const app = express();
app.post("/webhooks/keenauth", express.raw({ type: "application/json" }), (req, res) => {
let event;
try {
event = webhook.verify(req.body, req.headers);
} catch (e) {
if (e instanceof WebhookVerificationError) return res.status(400).send(e.kind);
throw e;
}
// event.type değerini işleyin, ardından hızlıca yanıt verin
res.sendStatus(204);
});
- SDK,
webhook-id,webhook-timestampvewebhook-signaturebaşlıklarını kontrol eder. Zaman damgası, sunucunuzun saatiyle her iki yönde de 5 dakika içinde olmalıdır. - Gizli anahtar döndürme sırasında her iki anahtarı da iletin:
new Webhook([newSecret, oldSecret]). Herhangi birv1imzası herhangi bir anahtarla eşleştiğinde istek kabul edilir. - İmzalar sabit sürede karşılaştırılır.
e.kind, neyin başarısız olduğunu belirtir:headers(bir başlık eksik),timestamp(sayı değil veya tolerans dışında),signature(hiçbir imza eşleşmiyor) veyasecret(yapılandırılan gizli anahtar geçerli biridp_whsec_değeri değil;new Webhooktarafından fırlatılan bir yapılandırma hatası). Her türünWebhookSignatureErrorgibi kendi sınıfı da vardır.verify, ayrıştırılmış JSON gövdesini döndürür.verifyRaw, doğrulanmış baytları döndürür.
Webhook'lar birden fazla kez gelebilir. Yinelenenleri yok saymak için webhook-id değerini kullanın.
Tipli olaylar ve talepler
@keenauth/node/events, herkese açık olay şemalarından üretilen her müşteri olayı için bir tip içerir. parseEvent, doğrulanmış bir gövdeyi kontrol eder ve KeenAuthEvent | UnknownEvent döndürür. isKnownEvent sonrasında switch (event.type), olayı tek bir tipe daraltır. @keenauth/node/webhooks içindeki verifyEvent her iki adımı birden yapar:
import { verifyEvent } from "@keenauth/node/webhooks";
import { isKnownEvent } from "@keenauth/node/events";
const event = verifyEvent(webhook, req.body, req.headers); // WebhookVerificationError veya EventParseError
if (!isKnownEvent(event)) {
// Bu SDK sürümünün henüz bilmediği bir tip. event.type ve event.data.object.id yine de tiplidir.
return res.sendStatus(204);
}
switch (event.type) {
case "user.created":
console.log(event.data.object.id);
break;
case "email_sending.suspended":
console.log(event.data.object.reason); // "bounce_rate" | "complaint_rate" | (string & {})
break;
}
parseEvent, JSON metnini, baytları veya zaten çözülmüş bir değeri kabul eder. Zarfı ve tipin şemasının tanımladığı üyeleri kontrol eder. Eksik veya yanlış tipte bir üye,data.object.reasongibi yolunu içeren birEventParseErrorfırlatır.- Bilinmeyen bir tip veya bu SDK'nın modellemediği bir
schema_versiondeğerine sahip bilinen bir tip, birUnknownEventolur. Bu bir hata değildir. - Şemada tanımlanmayan üyeler nesne üzerinde kalır.
- Sayılandırılmış alanlar, bilinen değerler artı
stringolarak tiplenir; böylece sunucudan gelen yeni bir değer yine tip denetiminden geçer ve ayrıştırılır.
@keenauth/node/claims, doğrulanmış bir token'ın taleplerini tiplendirir: parseIdTokenClaims (OpenID Connect Core) ve parseAccessTokenClaims (RFC 9068). Talep tiplerini kontrol ederler ancak hiçbir şeyi doğrulamazlar; bu yüzden doğrulayıcının döndürdüğü claims üzerinde çağırın:
import { parseAccessTokenClaims } from "@keenauth/node/claims";
const at = await verifier.verifyAccessToken(token);
const claims = parseAccessTokenClaims(at.claims);
claims.client_id; // string
claims.org_roles; // string[] | undefined
claims["tenant_tier"]; // unknown: kendi talepleriniz
Uygun olmayan bir talep, adını içeren bir ClaimsParseError fırlatır.
Kullanımdan kaldırma uyarıları
Bir yanıt Deprecation (RFC 9745) veya Sunset (RFC 8594) başlığı taşıdığında SDK, süreç yaşadığı sürece her uç nokta ve başlık değeri için bir uyarı yazar. Uyarı, yöntemi, kimlikler yerine {id} konmuş yolu ve başlık değerlerini içerir; token, sorgu dizesi veya kullanıcı verisi asla içermez. Hiçbir zaman hata fırlatmaz.
Varsayılan olarak uyarı, KeenAuthDeprecationWarning tipiyle process.emitWarning fonksiyonuna gönderilir. Uyarıyı bunun yerine kendi günlükçünüze göndermek için:
const keenauth = new KeenAuth({
baseUrl: "https://api.eu.keenauth.com/v1",
apiKey: process.env.KEENAUTH_API_KEY!,
onWarning: (message) => logger.warn(message),
});
Telemetri başlığı
Her istek Idp-Client: keenauth-ts/<version> (node/<version>) başlığını taşır. Kişisel veri içermez ve kapatılamaz; KeenAuth bunu destek amacıyla ve kullanımdan kaldırılmış SDK sürümleri hakkında sizi bilgilendirmek için kullanır.