Python sunucu SDK'sı
keenauth-python, Python 3.10 ve sonrası için sunucu SDK'sıdır. Yönetim API'sini tipli metotlarla çağırır ve tüm KeenAuth sunucu SDK'larının ortak davranışlarını ekler: API anahtarı ya da private_key_jwt makineden makineye token ile kimlik doğrulama, yeniden deneme, imleç ile sayfalama, tipli hatalar, webhook imza denetimleri ve kullanımdan kaldırma uyarıları. Paket henüz PyPI'da yayımlanmamıştır.
Bir web uygulamasında oturum açma için Django, Flask ve FastAPI sayfalarına bakın. Bearer token alan bir API'yi korumak için API'nizi koruma sayfasına bakın.
Kurulum
pip install keenauth-python
private_key_jwt imzalayıcısı cryptography paketini gerektirir. Bunu m2m ekiyle kurun:
pip install "keenauth-python[m2m]"
API anahtarı ile yönetim API'sini çağırma
import os
from keenauth import KeenAuth
client = KeenAuth("https://api.eu.keenauth.com/v1", os.environ["KEENAUTH_API_KEY"])
page = client.users.list_users(limit=20)
for user in page.data:
print(user.id)
Her oluşturulmuş API sınıfı bir özellik olarak kullanılabilir: client.users, client.organizations, client.api_keys ve benzerleri. Temel URL https kullanmalıdır; düz http yalnızca localhost için kabul edilir. SDK hiçbir yönlendirmeyi takip etmez; böylece kimlik bilgileriniz başka bir ana bilgisayara gönderilmez.
private_key_jwt yönetim token'ı kullanma
Bir yönetim uygulaması API anahtarı yerine özel anahtarıyla kimlik doğrulaması yapar. SDK bir istemci iddiası (RFC 7523) imzalar, ortamınızın token uç noktasından bir yönetim API token'ı alır ve süresi dolmadan 60 saniye önce yeniler:
import os
from keenauth import KeenAuth
from keenauth.m2m import ManagementTokenSource
source = ManagementTokenSource(
issuer="https://acme.eu.keenauth.app", # your environment's default host
client_id="app_01j9zzzzzzzzzzzzzzzzzzzz", # a management application
private_key=os.environ["KEENAUTH_PRIVATE_KEY"], # unencrypted PEM
resource="https://api.eu.keenauth.com", # the management API of your region
scopes=["users:read", "users:write"], # optional; default: the grant's default scopes
)
client = KeenAuth("https://api.eu.keenauth.com/v1", token_source=source)
- İddiada
issvesubdeğericlient_id,auddeğeri ise issuer'dır; rastgele birjtive 60 saniyelik bir ömrü vardır.kiddeğeri, genel anahtarın RFC 7638 parmak izidir. - Desteklenen anahtarlar: EC P-256 (
ES256), EC P-384 (ES384), Ed25519 (EdDSA) ve en az 2048 bit RSA (varsayılanPS256ya daalgorithm="RS256"). - Genel anahtarı yönetim uygulamasına kaydedin.
keenauth.m2m.load_private_key(pem).public_jwk()bunu bir JWK olarak döndürür. - Token önbelleğe alınır. Birden çok iş parçacığı aynı anda yeni token'a ihtiyaç duyduğunda token uç noktasına yalnızca bir istek gönderilir.
- Reddedilen bir istek,
status,errorveerror_descriptionalanlarıylakeenauth.m2m.TokenErrorfırlatır. Mesaj hiçbir zaman iddiayı ya da token'ı içermez.
Yeniden denemeler
SDK, 429, 502, 503 veya 504 ile başarısız olan ya da bağlantı hatası ya da zaman aşımı yaşanan istekleri yeniden dener. Yalnızca GET, PUT, DELETE ve bir Idempotency-Key taşıyan POST isteklerini yeniden dener. If-Match taşıyan bir PATCH yalnızca 429 durumunda 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. Toplamda en fazla 3 deneme yapılır.
- Yanıtta
Retry-Afterbaşlığı varsa (saniye ya da HTTP tarihi), SDK o kadar bekler.Retry-After60 saniyeden uzunsa SDK beklemez ve yanıtı size döndürür. Retry-Afteryoksa 0,5 saniye, ardından 1 saniye bekler; her beklemeye ±%25 rastgele jitter eklenir.- SDK, kabul eden her
POSTişlemine rastgele bir UUIDv4Idempotency-Keyekler; ancak kendiidempotency_key=değerinizi geçmediğiniz sürece. Yeniden deneme aynı anahtarı gönderir; böylece sunucu işlemi yalnızca bir kez çalıştırır.
Sayfalama
Liste metotları tek bir sayfa döndürür: after ve before imleçleriyle birlikte data ve list_metadata. paginate her sayfayı dolaşır ve sonraki sayfayı yalnızca ona ulaştığınızda getirir:
from keenauth import paginate
for user in paginate(client.users.list_users, limit=100, status="active"):
if user.email == "ada@example.com":
break # no further page is requested
- Filtreler ve
ordergibi diğer argümanlar her sayfa isteğiyle birlikte gönderilir. - Bir imleçten geriye doğru gezinmek için
before=geçin.aftervebeforebirlikte kullanılamaz. pages(...)aynı argümanları alır ve öğeler yerine tüm sayfaları döndürür.
Hatalar
application/problem+json (RFC 9457) biçimindeki bir hata yanıtı keenauth.ProblemError fırlatır. Alanlarından code, status, detail, request_id ve errors değerlerini kullanın. Bu SDK sürümünün bilmediği bir code yine de metin olarak döndürülür; böylece yeni sunucu hata kodları kodunuzu bozmaz.
from keenauth import ProblemError
try:
client.users.get_user("usr_01j9zzzzzzzzzzzzzzzzzzzz")
except ProblemError as e:
if e.code == "not_found":
...
print(e.request_id)
Webhook'ları doğrulama
KeenAuth webhook'larını Standard Webhooks şemasıyla imzalar. WebhookVerifier, webhook-id, webhook-timestamp ve webhook-signature başlıklarını uç noktanızın idp_whsec_ sırrına karşı denetler:
import os
from flask import Flask, request
from keenauth.webhooks import WebhookVerificationError, WebhookVerifier
app = Flask(__name__)
verifier = WebhookVerifier(os.environ["KEENAUTH_WEBHOOK_SECRET"])
@app.post("/webhooks/keenauth")
def keenauth_webhook():
try:
verifier.verify(request.get_data(), request.headers)
except WebhookVerificationError as e:
return {"error": e.reason}, 400
event = request.get_json()
...
return "", 204
- İşlenmemiş istek gövdesini, JSON ayrıştırmasından önce geçin; değişen tek bir bayt bile denetimi başarısız kılar.
- Zaman damgası, sunucunuzun saatiyle her iki yönde de 5 dakika içinde olmalıdır.
- Sırrı döndürürken ikisini birden geçin:
WebhookVerifier([new_secret, old_secret]). Başlıktaki herhangi bir imza herhangi bir sırla eşleştiğinde istek kabul edilir. - Hatalar tiplidir:
WebhookHeadersError,WebhookTimestampError,WebhookSignatureErrorveWebhookSecretError(hatalı biçimli sır; doğrulayıcı oluşturulduğunda fırlatılır). Her birinin birreasonalanı vardır. - Karşılaştırma sabit sürede yapılır; hata mesajı hiçbir zaman sırrı ya da imzayı içermez.
Tipli olaylar ve iddialar
keenauth.events, genel olay schema'larından üretilen her müşteri olay türü için dondurulmuş bir dataclass içerir. parse_event, doğrulanmış bir gövdeyi kontrol eder ve türünün sınıfını döndürür. keenauth.webhooks.verify_event doğrulama ve ayrıştırmayı tek çağrıda yapar. match ya da isinstance ile daraltın:
from keenauth.events import EmailSendingSuspendedEvent, UnknownEvent, UserCreatedEvent
from keenauth.webhooks import verify_event
event = verify_event(verifier, request.get_data(), request.headers)
match event:
case UserCreatedEvent():
print(event.data.object.id)
case EmailSendingSuspendedEvent():
print(event.data.object.reason)
case UnknownEvent():
pass # a type this SDK version does not know yet; event.type and event.raw are still available
parse_eventbayt, metin ya da zaten çözümlenmiş bir eşleme kabul eder. Zarfı ve türün schema'sının tanımladığı alanları denetler. Eksik ya da yanlış türde bir alan,data.object.reasongibi yolunu içeren birEventParseErrorfırlatır.- Bilinmeyen bir tür ya da bu SDK'nın modellemediği bir
schema_versiondeğerine sahip bilinen bir tür, birUnknownEventolur. Bu bir hata değildir. - Schema'nın tanımlamadığı alanlar
rawiçinde saklanır (olayda vedata.objectüzerinde). - Diziler tuple olarak temsil edilir. Sabit listeli alanların değerleri bilinen değerlere karşı denetlenmez.
- Modeller
mypy --strictdenetimini geçer.
keenauth.claims, doğrulanmış bir token'ın iddialarını tiplendirir: parse_id_token_claims (OpenID Connect Core) ve parse_access_token_claims (RFC 9068). Bunlar iddia türlerini denetler ama hiçbir şeyi doğrulamaz; bu yüzden doğrulayıcının döndürdüğü claims üzerinde çağırın:
from keenauth.claims import parse_access_token_claims
at = verifier.verify_access_token(token)
claims = parse_access_token_claims(at.claims)
claims.client_id # str
claims.org_roles # tuple[str, ...] | None
claims.custom # your own claims
aud her zaman bir tuple'dır. Uymayan bir iddia, adıyla birlikte ClaimsParseError fırlatır.
Kullanımdan kaldırma uyarıları
Bir yanıtta Deprecation (RFC 9745) ya da Sunset (RFC 8594) başlığı bulunduğunda SDK, süreç başına bir uyarıyı standart logging modülüyle keenauth logger'ına yazar. Uyarı metodu, kaynağı ve başlık değerlerini belirtir; hiçbir zaman kimlik, sorgu dizesi ya da kimlik bilgisi içermez. İstek kendisi etkilenmez.
import logging
logging.getLogger("keenauth").setLevel(logging.WARNING)
Telemetri başlığı
Her istek Idp-Client: keenauth-python/<version> (python/<version>) başlığını taşır. Kişisel veri içermez ve kapatılamaz; KeenAuth bunu destek ve kullanımdan kaldırma bildirimleri için kullanır.