Yetkilendirme¶
API Market iki OAuth2 akışı kullanır. Her uç noktanın hangi akışı ve hangi kapsamı (scope) istediği dokümanda yazar; kütüphane bunu bilir ve doğru token'ı kendisi seçer.
| Client credentials | Authorization code | |
|---|---|---|
| Kim adına | Uygulamanın (kurumun) kendisi | Giriş yapan müşteri |
| Giriş ekranı | Yok | Müşteri bankanın sayfasında giriş yapar |
| Sizin yapmanız gereken | Hiçbir şey | Müşteriyi yönlendirmek, callback'i karşılamak |
| Örnek uç nokta | kt.accounts.account_list_v3() |
kt.tpp_accounts.account_list_v2() |
| Token süresi | 1 saat, otomatik yenilenir | Access 1 saat, refresh 24 saat |
Client credentials¶
Ek bir adım gerekmez:
İstemci ilk çağrıda accounts kapsamı için token alır, bellekte saklar ve süresi dolmadan
yeniler. Her kapsam için ayrı token alınır.
Kimse giriş yapmadıysa hangi hesaplar dönüyor?
Bu akışta dönen veriler, API Market uygulamanızın bağlı olduğu müşteriye aittir. Sandbox'ta bu, portalın uygulamanıza atadığı test kurumsal müşterisidir; canlıda API'yi kullanan kurumun kendisidir. Başka bir müşterinin verisine bu akışla erişilemez.
Uygulamanız bir kapsama yetkili değilse token alınamaz ve
AuthenticationError fırlatılır (invalid_scope). Portalda uygulamanıza ilgili API ürününü
eklemeniz gerekir.
Authorization code (müşteri girişi)¶
Müşteri bankanın sayfasında oturum açıp uygulamanıza izin verir; banka tarayıcıyı bir code
ile sizin Redirect URI'nize geri yollar; siz bu kodu token'a çevirirsiniz.
Betikler ve geliştirme: login()¶
Redirect URI'niz http://localhost:PORT/... biçimindeyse tek satır yeter. Tarayıcı açılır, o
portta geçici bir sunucu callback'i yakalar ve token alınır:
from kuveytturk_api import FileTokenStore, KuveytTurk
kt = KuveytTurk.from_env(".env", token_store=FileTokenStore(".kuveytturk/tokens.json"))
if kt.auth.get_user_token() is None:
kt.auth.login(["accounts", "offline_access"])
hesaplar = kt.tpp_accounts.account_list_v2()
offline_access kapsamı refresh token verilmesini sağlar. FileTokenStore sayesinde betiği
yeniden çalıştırdığınızda tekrar giriş istenmez (refresh token geçerli olduğu sürece).
Sandbox'ta giriş için geliştirici portalındaki test müşterilerini kullanın; giriş sonrası istenen tek kullanımlık şifre için 6 haneli herhangi bir kod kabul edilir.
Web uygulamaları¶
Yönlendirmeyi ve callback'i kendi rotalarınızda yaparsınız:
# 1) Kullanıcıyı bankaya yönlendirin
state = kt.auth.new_state() # oturumda saklayın
url = kt.auth.authorization_url(["accounts", "offline_access"], state=state)
# 2) Redirect URI'nize dönen istekte
code = kt.auth.parse_callback(request_url, state=state)
kt.auth.exchange_code(code, user="musteri-42") # token bu anahtarla saklanır
# 3) O müşteri adına çağrı yapın
hesaplar = kt.as_user("musteri-42").tpp_accounts.account_list_v2()
state, callback'in gerçekten sizin başlattığınız girişe ait olduğunu doğrular (CSRF koruması);
parse_callback uyuşmazlıkta AuthenticationError fırlatır. Çalışan tam bir örnek:
Web uygulamasında müşteri girişi.
Token'ın ömrü¶
- Access token 1 saat geçerlidir. Süresi dolduğunda kütüphane refresh token ile yenisini alır; sizin bir şey yapmanız gerekmez.
- Refresh token 24 saat geçerlidir ve her yenilemede değişir. Kütüphane yenisini depoya yazar. Bu yüzden kalıcı bir depo kullanıyorsanız yazma işleminin güvenilir olması önemlidir: yeni refresh token kaydedilemeden kaybolursa müşterinin yeniden giriş yapması gerekir.
- Yenileme mümkün değilse
AuthorizationRequiredErrorfırlatılır; müşteriyi yeniden giriş akışına yönlendirin.
Çok kullanıcılı kullanım: as_user()¶
Müşteri token'ları bir kullanıcı anahtarıyla saklanır. kt.as_user("anahtar"), o müşterinin
token'ını kullanan hafif bir istemci görünümü döndürür; bağlantıları ve token deposunu ana
istemciyle paylaşır.
kt.auth.exchange_code(code, user="ali")
kt.auth.exchange_code(baska_kod, user="veli")
kt.as_user("ali").tpp_accounts.account_list_v2() # Ali'nin hesapları
kt.as_user("veli").tpp_accounts.account_list_v2() # Veli'nin hesapları
Anahtar verilmezse "default" kullanılır; tek kullanıcılı betiklerde bunu düşünmeniz gerekmez.
Token'ları saklamak¶
Token'lar varsayılan olarak yalnızca süreç belleğinde tutulur.
| Depo | Ne zaman |
|---|---|
MemoryTokenStore (varsayılan) |
Yalnızca client credentials kullanan ya da kısa ömürlü süreçler |
FileTokenStore("yol.json") |
Betikler ve masaüstü araçları; dosya 0600 izinleriyle yazılır |
| Kendi deponuz | Web uygulamaları, birden çok süreç ya da sunucu |
Kendi deponuz için üç metot yeterlidir:
from kuveytturk_api import Token
class RedisTokenStore:
def __init__(self, redis):
self.redis = redis
def get(self, key: str) -> Token | None:
raw = self.redis.get(f"kt:{key}")
return Token.from_dict(json.loads(raw)) if raw else None
def set(self, key: str, token: Token) -> None:
self.redis.set(f"kt:{key}", json.dumps(token.to_dict()))
def delete(self, key: str) -> None:
self.redis.delete(f"kt:{key}")
kt = KuveytTurk.from_env(token_store=RedisTokenStore(redis_client))
Anahtarlar client:<kapsam> (uygulama token'ları) ve user:<kullanıcı> (müşteri token'ları)
biçimindedir. Token'lar hesaba erişim sağlar; şifreli saklayın ve loglara yazmayın.
Bir çağrıda akışı ya da token'ı değiştirmek¶
Doküman bir uç noktanın akışını yanlış belirtmişse ya da elinizde hazır bir token varsa
request_options ile ezebilirsiniz:
kt.accounts.account_list_v3(request_options={"flow": "authorization_code", "user": "ali"})
kt.accounts.account_list_v3(request_options={"token": "hazir-access-token"})
Ayrıntı: Doğrudan istek ve kaçış yolları.