Express API'sini koruyun
Bu hızlı başlangıç, bir Express 5 API'sini KeenAuth erişim belirteçleriyle korur. Node.js SDK'sının expressAuth ara katmanını eklersiniz, bir rotada bir kapsam zorunlu kılarsınız ve API'yi SDK test kiti ile çevrimdışı test edersiniz. Express, SDK'nın bağımlılığı değildir; ara katman Express 4 ile de çalışır.
API'nin üç uç noktası vardır:
| Uç nokta | Gereksinim |
|---|---|
GET /api/public |
yok |
GET /api/private |
API'niz için geçerli bir erişim belirteci |
GET /api/messages |
messages:read kapsamına sahip geçerli bir erişim belirteci |
Başlamadan önce
- Bir KeenAuth ortamı. Yayıncısı
https://your-environment.eu.keenauth.appgibi görünür. - Ortamda kayıtlı bir API (API oluşturun). Bunun
identifier(örneğinhttps://api.example.com), API'nizin kabul ettiği belirteçlerin hedef kitlesidir. - Bu API üzerinde
messages:readkapsamı, onu çağıran uygulamaya verilmiş olmalıdır. - Node.js 22 veya daha yeni bir sürüm.
1. SDK'yı yükleyin
npm install @keenauth/node express@5.2.1
SDK henüz yayımlanmadı. Yayımlanana kadar örnek, SDK kaynağını package.json içinde bağlantılar.
2. Yapılandırın
API yapılandırmasını yalnızca ortam değişkenlerinden okur. Bunları bir .env dosyasına koyun; npm start bu dosyayı node --env-file-if-exists=.env ile yükler ve dosyayı asla commit etmeyin.
| Değişken | Gerekli | Anlamı |
|---|---|---|
KEENAUTH_ISSUER |
evet | Ortamınızın yayıncısı |
KEENAUTH_AUDIENCE |
evet | API'nizin tanımlayıcısı |
PUBLIC_BASE_URL |
evet | İstemcilerin çağırdığı URL (bkz. Proxy arkasında) |
KEENAUTH_WEBHOOK_SECRET |
önerilir | idp_whsec_ imza sırrı, token.revoked teslim eden webhook uç noktasının sırrıdır (belirteçleri döndürürken virgülle ayrılmış iki değer). Bu olmadan API, iptal edilmiş belirteçlerden haberdar olmaz |
PORT |
hayır | Dinleme portu, varsayılan 8080 |
3. Rotalarınızı koruyun
createApp koruyucuyu ve rotaları oluşturur. expressAuth(protector) geçerli bir belirteç gerektirir; { scopes } ile birlikte kapsamları da gerektirir. İşleyici, doğrulanmış talepleri req.auth üzerinden okur.
export function createApp({ verifier, publicBaseUrl, revocation, webhookSecrets = [] }) {
const protector = createProtector(verifier, {
publicBaseUrl,
revocation,
// The error never contains the token or claim values; never log the Authorization or DPoP header.
onError: (err) => console.warn(`rejected: ${err.message}`),
});
const app = express();
app.disable("x-powered-by");
// No token needed.
app.get("/api/public", (req, res) => {
res.json({ message: "Hello from a public endpoint." });
});
// Any valid access token for this API.
app.get("/api/private", expressAuth(protector), (req, res) => {
res.json({ message: "Hello from a private endpoint.", sub: req.auth.subject });
});
// A valid access token that also carries the messages:read scope.
app.get("/api/messages", expressAuth(protector, { scopes: ["messages:read"] }), (req, res) => {
res.json({ messages: ["Hello from a scoped endpoint."] });
});
// token.revoked deliveries from KeenAuth; the handler reads the raw body itself, so no JSON parser runs before it.
if (webhookSecrets.length > 0) {
app.post(WEBHOOK_PATH, ...createWebhookHandler({ secrets: webhookSecrets, revocation }));
} else {
console.warn("KEENAUTH_WEBHOOK_SECRET is not set: token.revoked events are not received, so revoked tokens stay valid until they expire");
}
return app;
}
server.js yapılandırmadan gerçek doğrulayıcıyı oluşturur. Doğrulayıcı, bir belirteci ilk gördüğünde imza anahtarlarını ortamınızdan alır.
const issuer = process.env.KEENAUTH_ISSUER;
const audience = process.env.KEENAUTH_AUDIENCE;
// The URL clients call: DPoP proofs are checked against it, never against the Host header.
const publicBaseUrl = process.env.PUBLIC_BASE_URL;
if (!issuer || !audience || !publicBaseUrl) {
console.error("KEENAUTH_ISSUER, KEENAUTH_AUDIENCE and PUBLIC_BASE_URL are required");
process.exit(1);
}
// createVerifier refuses an issuer under the reserved .invalid domain, so a test token can never pass here.
const verifier = createVerifier({ issuer, audience });
const revocation = createMemoryRevocationCache();
// The signing secret (idp_whsec_...) of the webhook endpoint that delivers token.revoked; comma separated while rotating.
const webhookSecrets = (process.env.KEENAUTH_WEBHOOK_SECRET ?? "").split(",").map((s) => s.trim()).filter(Boolean);
const app = createApp({ verifier, publicBaseUrl, revocation, webhookSecrets });
const port = Number(process.env.PORT || 8080);
app.listen(port, () => console.log(`listening on port ${port}`));
4. API'yi çalıştırın ve çağırın
npm start
İlk çağrı için, API'nizde messages:read kapsamına sahip bir makineden makineye uygulamanın istemci kimlik bilgileri akışıyla bir belirteç alın:
ACCESS_TOKEN=$(curl -s -u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=client_credentials \
-d resource=https://api.example.com \
-d scope=messages:read \
https://your-environment.eu.keenauth.app/oauth2/token | jq -r .access_token)
curl -i http://localhost:8080/api/messages -H "Authorization: Bearer $ACCESS_TOKEN"
5. Ağ olmadan test edin
@keenauth/node/testing, herkese açık bir test anahtarıyla imzalanmış belirteçler üretir ve createTestVerifier yalnızca bu belirteçleri kabul eder. Testler bu doğrulayıcıyı createApp aktarır ve uygulamayı yerel bir bağlantı noktasında çağırır; bu nedenle ağ ya da KeenAuth hesabı gerekmez. Bkz. Çevrimdışı test kiti.
test("scope check: 403 insufficient_scope without messages:read, 200 with it", async () => {
await expectProblem(await get("/api/messages", bearer(mintAccessToken(AUDIENCE))), 403, "insufficient_scope", /scope="messages:read"/);
const ok = await get("/api/messages", bearer(mintAccessToken(AUDIENCE, { claims: { scope: "profile messages:read" } })));
assert.equal(ok.status, 200);
});
npm test
Örneğin testleri, geçerli bir belirtecin kabul edildiğini; eksik, süresi dolmuş ya da yanlış hedef kitleli belirteçlerin, eksik kapsamın, URL sorgusundaki belirtecin ve iptal edilmiş belirtecin aşağıdaki durum kodlarıyla reddedildiğini denetler. Ayrıca PUBLIC_BASE_URL için bir kanıtla DPoP'a bağlı bir belirteç gönderirler ve server. The tests also send signed token.revokeddeliveries: a valid one revokes the token, a forged, tampered or stale one gets400 and revokes nothing, and a repeated one has one effect.js test yayıncısıyla başlatılmayı reddettiğini kontrol ederler.
Yanıtlar
| İstek | Durum | code gövdesinde |
|---|---|---|
Authorization başlığı yok |
401 |
missing_token |
| Süresi dolmuş belirteç, başka bir API için belirteç, geçersiz imza, iptal edilmiş belirteç | 401 |
invalid_token |
| Gerekli kapsamı olmayan belirteç | 403 |
insufficient_scope |
URL sorgusundaki belirteç (?access_token=) |
400 |
invalid_request |
Gövde application/problem+json biçimindedir ve WWW-Authenticate başlığı standart meydan okumayı taşır. Tam tablo Ara katmanla API'nizi koruma sayfasındadır.
Proxy arkasında
İstemciler DPoP kullanıyorsa ara katman, her kanıtın istemcinin çağırdığı URL için yapıldığını denetler. PUBLIC_BASE_URL değerini, örneğin https://api.example.com, istemcilerin çağırdığı harici URL'ye ayarlayın; proxy veya yük dengeleyici arkasında da böyle yapın. Bu zorunludur ve https kullanmalıdır (http yalnızca localhost, 127.0.0.1 veya [::1] için); bu olmadan uygulama başlamayı reddeder. Ara katman, Express'in trust proxy ayarı ne olursa olsun X-Forwarded-* başlıklarına asla güvenmez.
İptal edilmiş belirteçler
Bir erişim belirteci süresi dolana kadar geçerli kalır; bu yüzden KeenAuth, belirteçler iptal edildiğinde API'nize bildirir. Örnek, koruyucuya bellek içi bir iptal önbelleği verir ve bunu besleyen bir token.revoked webhook'unu POST /webhooks/keenauth (webhook.js) adresinde sunar.
- Kontrol panelinde,
https://<your host>/webhooks/keenauthURL'si ile bir webhook uç noktası oluşturun,token.revokedolaylarına abone olun ve imza sırrınıKEENAUTH_WEBHOOK_SECRETolarak dışa aktarın. - İşleyici, imzayı ham gövde üzerinde SDK ile doğrular ve geçersiz olduğunda ya da zaman damgası beş dakikadan fazla saptığında
400yanıtı verir. Olayın seçicisini (access_token,session,user,client,org,org_user,client_user) bir iptal işaretçisine eşler ve204yanıtı verir; ara katman bundan sonra,not_beforetarihinden önce verilmiş eşleşen her belirteci reddeder. - KeenAuth en az bir kez teslim eder; bu nedenle işleyici her
webhook-idolayını yalnızca bir kez uygular. İşaretçi saklanamazsa503yanıtı verir ve KeenAuth olayı yeniden teslim eder. Diğer olay türlerini ve hiçbir erişim belirteciyle eşleşemeyecek seçicileri (refresh_family,api) yok sayar.
İşleyici; olay kimliğini, seçici türünü ve nedeni kaydeder, gövdeyi, imzayı ya da sırrı asla kaydetmez. Her süreç kendi önbelleğine sahiptir; birden çok örnekte, işaretçileri aynı revoke yöntemi arkasında paylaşılan bir depoya koyun. Bkz. İptal önbelleği.
Sonraki adımlar
- Ara katmanla API'nizi koruma: Fastify, adım yükseltme gereksinimleri, DPoP ve tüm seçenekler.
- Belirteç doğrulama: ara katmanın altındaki doğrulayıcı.
- Çevrimdışı test kiti.