JWT Decoder Python — PyJWT ile JWT Çözme Rehberi

·DevOps Engineer & Python Automation Specialist·İnceleyenMaria Santos·Yayınlandı

Ücretsiz JWT Kod Çözücü aracını doğrudan tarayıcınızda kullanın — kurulum gerektirmez.

JWT Kod Çözücü Online Dene →

Token tabanlı kimlik doğrulama kullanan her API, bir noktada size bir JWT verir; içinde ne olduğunu çözmek ise geliştirme sürecinde sürekli karşılaşılan bir iştir. Python'daki bir JWT çözücü, o opak base64 dizisini gerçekten çalışabileceğiniz okunabilir bir iddiaları sözlüğüne dönüştürür. İhtiyacınız olan PyPI paketi PyJWT pip install PyJWT ile kurulur ancak import jwt olarak içe aktarılır. Bu kılavuz; jwt.decode() ile tam imza doğrulaması, hızlı inceleme için gizli anahtar olmadan çözme, herhangi bir kütüphane kullanmadan manuel base64 çözme, RS256 açık anahtar doğrulaması ve üretim kimlik doğrulama sistemlerinde karşılaşılan yaygın tuzakları ele alır. Hızlı tek seferlik bir kontrol için çevrimiçi JWT Çözücü bunu hiç kod yazmadan anında yapar. Tüm örnekler Python 3.10+ ve PyJWT 2.x hedef alır.

  • pip install PyJWT, ardından import jwt — paket adı ve import adı farklıdır; bu neredeyse herkesi şaşırtır.
  • jwt.decode(token, key, algorithms=["HS256"]) iddiaları içeren düz bir dict döndürür. algorithms parametresini her zaman açıkça belirtin.
  • İddiaları doğrulamadan incelemek için: jwt.decode(token, options={"verify_signature": False}, algorithms=["HS256"]).
  • RSA/EC token'ları için: pip install PyJWT cryptography — asimetrik algoritmalar için cryptography arka ucu gereklidir.
  • Manuel çözme (base64 + json) herhangi bir kütüphane olmadan çalışır ancak imza ve son kullanma doğrulamasını atlar.

JWT Çözme Nedir?

Bir JSON Web Token, noktalara göre ayrılmış üç base64url kodlu segmentten oluşur: bir başlık (algoritma ve token türü), bir payload (iddialar — kullanıcı kimliği, roller, son kullanma zamanı) ve bir imza. JWT çözmek; başlık ve payload segmentlerini ayıklamak, bunları base64url ile çözmek ve ortaya çıkan JSON'ı bir iddiaları sözlüğüne ayrıştırmak demektir.

Başlık, token'ı imzalamak için hangi algoritmanın kullanıldığını ve bazen doğru doğrulama anahtarını bulmak için kid (anahtar kimliği) içerir. Payload, gerçek veriyi barındırır: token kime verildi (sub), ne zaman sona eriyor (exp), hangi servis için tasarlandı (aud) ve uygulamanızın tanımladığı özel iddialar. İmza segmenti, token'ın değiştirilmediğini kanıtlar; ancak doğrulamak için gizli anahtara veya açık anahtara ihtiyaç duyarsınız. Çözme ve doğrulama birbirinden bağımsız işlemlerdir. Payload'ı imzayı doğrulamadan çözebilirsiniz (hata ayıklama için kullanışlıdır), ancak yetkilendirme kararları için asla doğrulanmamış iddialara güvenmeyin.

Before · json
After · json
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfOGYyYSIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTcxMTgxNTYwMH0.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
{
  "sub": "usr_8f2a",
  "role": "admin",
  "exp": 1711815600
}

jwt.decode() — PyJWT ile Çözme ve Doğrulama

jwt.decode() PyJWT kütüphanesinin temel fonksiyonudur. Kodlanmış token dizisini, gizli anahtarı (HMAC algoritmaları için) veya açık anahtarı (RSA/EC için) ve zorunlu algorithms listesini alır. Fonksiyon imzayı doğrular, exp ve nbf gibi standart iddiaları kontrol eder ve payload'ı Python sözlüğü olarak döndürür. Herhangi bir şey başarısız olursa — hatalı imza, süresi dolmuş token, yanlış algoritma — özel bir hata fırlatır.

Minimal Çalışan Örnek

Python 3.10+
import jwt

# Veren ile bu servis arasında paylaşılan gizli anahtar
SECRET_KEY = "k8s-webhook-signing-secret-2026"

# Önce bir token kodlayın (kimlik doğrulama sunucusunun vereceğini simüle eder)
token = jwt.encode(
    {"sub": "usr_8f2a", "role": "admin", "team": "platform"},
    SECRET_KEY,
    algorithm="HS256"
)
print(token)
# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3Jf...

# Token'ı çöz ve doğrula
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
print(payload)
# {'sub': 'usr_8f2a', 'role': 'admin', 'team': 'platform'}
print(payload["role"])
# admin

algorithms parametresi tek bir dize değil, bir listedir ve PyJWT 2.x'te zorunludur. Bu bir güvenlik özelliğidir: olmadan, bir saldırgan başlığa alg: none içeren bir token oluşturabilir ve doğrulamayı tamamen atlayabilir. Uygulamanızın kabul ettiği algoritmayı her zaman açıkça belirtin. Yalnızca HS256 token'ları yayınlıyorsanız liste ["HS256"] olmalıdır — ["HS256", "RS256", "none"] değil. Listeyi kısa tutmak saldırı yüzeyini azaltır.

Başlangıçta beni şaşırtan bir durum: PyJWT 2.x, jwt.encode() fonksiyonunu bytes yerine string döndürecek şekilde değiştirdi. Kodlanmış token üzerinde .decode("utf-8") çağıran eski Stack Overflow yanıtlarını görüyorsanız, o kod PyJWT 1.x dönemine aittir ve 2.x sürümünde AttributeError fırlatır. Token zaten bir string — doğrudan kullanın.

Son Kullanma Tarihiyle Tam Gidiş-Dönüş

Python 3.10+ — encode then decode with exp
import jwt
from datetime import datetime, timedelta, timezone

SECRET_KEY = "webhook-processor-secret"

# 1 saat içinde sona eren bir token oluşturun
payload = {
    "sub": "svc_payment_processor",
    "iss": "auth.internal.example.com",
    "aud": "https://api.example.com",
    "exp": datetime.now(timezone.utc) + timedelta(hours=1),
    "permissions": ["orders:read", "refunds:create"],
}

token = jwt.encode(payload, SECRET_KEY, algorithm="HS256")

# Daha sonra, token bir istek başlığında geldiğinde:
try:
    decoded = jwt.decode(
        token,
        SECRET_KEY,
        algorithms=["HS256"],
        audience="https://api.example.com",
        issuer="auth.internal.example.com",
    )
    print(f"Servis: {decoded['sub']}")
    print(f"İzinler: {decoded['permissions']}")
except jwt.ExpiredSignatureError:
    print("Token süresi doldu — yeniden kimlik doğrulama gerekli")
except jwt.InvalidAudienceError:
    print("Token bu API için tasarlanmamış")
except jwt.InvalidIssuerError:
    print("Token bilinmeyen bir yetkili tarafından verildi")
Not:PyJWT, kodlama sırasında datetime nesnelerini otomatik olarak Unix zaman damgasına dönüştürür. Çözme sırasında exp, iat ve nbf iddiaları datetime nesnesi değil, tamsayı olarak gelir. Bunları kendiniz datetime.fromtimestamp(payload["exp"], tz=timezone.utc) ile dönüştürmeniz gerekir.

JWT'yi İmza Doğrulaması Olmadan Çözme

Bazen token'ı doğrulayabilmeden önce iddiaları okumanız gerekir. Yaygın bir senaryo: token başlığında bir kid (anahtar kimliği) alanı bulunur ve doğrulamadan önce bir JWKS uç noktasından eşleşen açık anahtarı almanız gerekir. PyJWT bunu verify_signature: False seçeneğiyle destekler. algorithms listesini yine geçersiniz, ancak key argümanı göz ardı edilir.

Python 3.10+ — unverified decode
import jwt

token = (
    "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InNpZy0xNzI2In0"
    ".eyJzdWIiOiJ1c3JfM2M3ZiIsInNjb3BlIjoicmVhZDpvcmRlcnMiLCJpc3MiOiJhdXRoLmV4YW1wbGUuY29tIn0"
    ".signature_placeholder"
)

# Adım 1: Yönlendirme bilgisini almak için doğrulamasız iddiaları oku
unverified = jwt.decode(
    token,
    options={"verify_signature": False},
    algorithms=["RS256"]
)
print(unverified)
# {'sub': 'usr_3c7f', 'scope': 'read:orders', 'iss': 'auth.example.com'}

# Adım 2: Hangi anahtarın kullanılacağını bulmak için başlığı oku
header = jwt.get_unverified_header(token)
print(header)
# {'alg': 'RS256', 'typ': 'JWT', 'kid': 'sig-1726'}
# Şimdi doğru açık anahtarı JWKS uç noktanızdan almak için header['kid'] kullanın
Uyarı:Doğrulanmamış token'lara güvenilmez. Bu kalıbı yalnızca yönlendirme kararları için kullanın (hangi anahtarı alacağınız, hangi kiracıyı arayacağınız). Doğrulanmamış iddialara dayanarak asla yetkilendirme kararı vermeyin. Saldırgan payload'a istediği her şeyi yazabilir.

Burada ince bir ayrım var. jwt.get_unverified_header() yalnızca başlığı — ilk segmenti — okur. verify_signature: False seçeneğiyle yapılan jwt.decode() çağrısı ise payload'ı (ikinci segment) okur. İkisini birlikte kullanarak bir anahtara gerek duymadan token'dan her şeyi çıkarabilirsiniz. İmza doğrulaması kapalı olsa bile PyJWT, token'ın doğru yapıda olduğunu (nokta ile ayrılmış üç segment, geçerli base64, geçerli JSON) doğrular. Token yapısal olarak hatalıysa, geçirdiğiniz seçeneklerden bağımsız olarak DecodeError fırlatır.

jwt.decode() Parametre Referansı

Tam imza şudur: jwt.decode(jwt, key, algorithms, options, audience, issuer, leeway, require). algorithms sonrasındaki tüm parametreler yalnızca anahtar kelime olarak geçirilir.

Parametre
Tür
Varsayılan
Açıklama
jwt
str | bytes
(zorunlu)
Çözülecek kodlanmış JWT dizisi
key
str | bytes | dict
(zorunlu)
Doğrulama için gizli anahtar (HMAC) veya açık anahtar (RSA/EC)
algorithms
list[str]
(zorunlu)
İzin verilen algoritmalar — ör. ["HS256"], ["RS256"]. Asla atlamayın.
options
dict
{}
Doğrulama bayraklarını geçersiz kılar: verify_signature, verify_exp, verify_aud vb.
audience
str | list[str]
None
Beklenen aud iddiası — uyuşmazlık durumunda InvalidAudienceError fırlatır
issuer
str
None
Beklenen iss iddiası — uyuşmazlık durumunda InvalidIssuerError fırlatır
leeway
timedelta | int
0
exp ve nbf kontrolleri için saat sapması toleransı (saniye)
require
list[str]
[]
Bulunması zorunlu iddialar — yoksa MissingRequiredClaimError fırlatır

options sözlüğü, PyJWT'nin hangi doğrulamaları yapacağı üzerinde ayrıntılı kontrol sağlar. Anahtarlar tek tek kontrollere karşılık gelir: verify_signature, verify_exp, verify_nbf, verify_iss, verify_aud ve verify_iat. Açıkça False olarak ayarlamadıkça hepsi varsayılan olarak True değerindedir. Üretimde tüm bu değerleri varsayılanlarında bırakın. Tek tek kontrolleri yalnızca geliştirme sırasında eski test token'larıyla çalışırken ve geçici olarak son kullanmayı atlamam gerektiğinde devre dışı bırakıyorum.

Python 3.10+ — using options and require
import jwt

# Belirli iddiaların mevcut olmasını zorunlu kıl — yoksa MissingRequiredClaimError fırlatır
payload = jwt.decode(
    token,
    SECRET_KEY,
    algorithms=["HS256"],
    options={"require": ["exp", "iss", "sub"]},
    issuer="auth.internal.example.com",
)

# Yalnızca geliştirme ortamında: eski token'ları test etmek için son kullanmayı atla
dev_payload = jwt.decode(
    token,
    SECRET_KEY,
    algorithms=["HS256"],
    options={"verify_exp": False},  # ÜRETİMDE KULLANMAYIN
)

base64 ve json ile Manuel JWT Çözme

Yalnızca Python standart kütüphanesini kullanarak bir JWT payload'ını çözebilirsiniz — pip install gerekmez. Bu, birkaç durumda gerçekten kullanışlıdır: bağımlılık eklemenin abartılı olacağı hata ayıklama betikleri, yalnızca standart kütüphanenin bulunduğu kısıtlı CI ortamları, soğuk başlatma süresini en aza indirmek istediğiniz AWS Lambda fonksiyonları veya bir JWT'nin perde arkasında ne olduğunu anlamak. Süreç oldukça basittir: noktalara göre bölün, istediğiniz segmenti alın, base64 dolgusu ekleyin, çözün ve JSON'ı ayrıştırın.

base64 ve json modülleri Python standart kütüphanesinde bulunduğundan, bu yaklaşım 3.6'dan itibaren herhangi bir Python kurulumunda çalışır. Aşağıdaki fonksiyonlar başlığı (ilk segment) ve payload'ı (ikinci segment) ayrı ayrı işler:

Python 3.10+ — manual JWT decode without any library
import base64
import json

def decode_jwt_payload(token: str) -> dict:
    """İmza doğrulaması olmadan JWT payload'ını çöz.
    HS256, RS256, ES256 vb. tüm JWT'lerle çalışır.
    """
    parts = token.split(".")
    if len(parts) != 3:
        raise ValueError(f"Expected 3 JWT segments, got {len(parts)}")

    payload_b64 = parts[1]
    # base64url, + ve / yerine - ve _ kullanır
    # Python'ın urlsafe_b64decode bunu işler, ancak dolgu gerektirir
    payload_b64 += "=" * (-len(payload_b64) % 4)
    payload_bytes = base64.urlsafe_b64decode(payload_b64)
    return json.loads(payload_bytes)


def decode_jwt_header(token: str) -> dict:
    """JWT başlığını çöz (algoritma, anahtar kimliği, tür)."""
    header_b64 = token.split(".")[0]
    header_b64 += "=" * (-len(header_b64) % 4)
    return json.loads(base64.urlsafe_b64decode(header_b64))


# Kullanım örneği
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfOGYyYSIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTcxMTgxNTYwMH0.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

header = decode_jwt_header(token)
print(f"Algorithm: {header['alg']}")
# Algorithm: HS256

claims = decode_jwt_payload(token)
print(f"Subject: {claims['sub']}")
print(f"Role: {claims['role']}")
# Subject: usr_8f2a
# Role: admin

Dolgu numarası (+= "=" * (-len(s) % 4)), herkesin unuttuğu kısımdır. JWT base64url, sondaki = karakterlerini atlar, ancak Python'ın urlsafe_b64decode fonksiyonu bunları gerektirir. Dolgu düzeltmesi olmadan binascii.Error: Incorrect padding hatası alırsınız.

Not:Manuel çözme imzayı doğrulamaz. Herkes bir JWT'nin payload'ını değiştirip yeniden kodlayabilir. Bu yaklaşımı yalnızca inceleme ve hata ayıklama için kullanın, asla yetkilendirme mantığı için değil. Önemli bir şey için jwt.decode() fonksiyonunu gerçek bir anahtarla kullanın.

API Yanıtlarından ve Token Dosyalarından JWT Çözme

En yaygın iki gerçek dünya senaryosu: bir HTTP yanıtından JWT ayıklamak (OAuth token uç noktası, giriş API'si) ve dosyalardan token okumak (servis hesabı kimlik bilgileri, Kubernetes monte edilmiş sırları, diskte önbelleğe alınmış tokenlar). Her ikisi de uygun hata işleme gerektirir. Ağ istekleri başarısız olabilir. Dosyalar kaybolabilir. Token'lar önbelleğe alındıktan sonra okunmadan önce sona erebilir.

Aşağıdaki örnekler HTTP çağrıları için httpx kullanır (tercih ederseniz requests ile değiştirebilirsiniz, kalıp aynıdır) ve dosya işlemleri için pathlib.Path kullanır. Her örnek, genel bir except Exception yerine belirli PyJWT istisnalarını yakalar; böylece her hata moduna uygun şekilde yanıt verebilirsiniz: sona ermede yeniden kimlik doğrulama, imza hatasında uyarı, ağ zaman aşımında yeniden deneme.

API Yanıtından JWT Çözme

Python 3.10+ — decode JWT from OAuth token endpoint
import jwt
import httpx  # or requests

TOKEN_ENDPOINT = "https://auth.example.com/oauth/token"
SECRET_KEY = "shared-webhook-signing-key"

def get_and_decode_token() -> dict:
    """Kimlik doğrulama sunucusundan erişim token'ı al ve çöz."""
    try:
        response = httpx.post(
            TOKEN_ENDPOINT,
            data={
                "grant_type": "client_credentials",
                "client_id": "svc_order_processor",
                "client_secret": "cs_9f3a7b2e",
            },
            timeout=10.0,
        )
        response.raise_for_status()
    except httpx.HTTPError as exc:
        raise RuntimeError(f"Token request failed: {exc}") from exc

    token_data = response.json()
    access_token = token_data["access_token"]

    try:
        payload = jwt.decode(
            access_token,
            SECRET_KEY,
            algorithms=["HS256"],
            audience="https://api.example.com",
        )
        return payload
    except jwt.InvalidTokenError as exc:
        raise RuntimeError(f"Invalid token from auth server: {exc}") from exc


claims = get_and_decode_token()
print(f"Service: {claims['sub']}, Scopes: {claims.get('scope', 'none')}")

Dosyadan JWT Çözme

Python 3.10+ — read and decode a cached token file
import jwt
from pathlib import Path
from datetime import datetime, timezone

TOKEN_PATH = Path("/var/run/secrets/service-account-token")
PUBLIC_KEY_PATH = Path("/etc/ssl/auth/public_key.pem")

def decode_token_from_file() -> dict:
    """Dosyadan JWT oku, PEM açık anahtarıyla doğrula."""
    try:
        token = TOKEN_PATH.read_text().strip()
        public_key = PUBLIC_KEY_PATH.read_text()
    except FileNotFoundError as exc:
        raise RuntimeError(f"Missing file: {exc.filename}") from exc

    try:
        payload = jwt.decode(
            token,
            public_key,
            algorithms=["RS256"],
            audience="https://internal-api.example.com",
        )
    except jwt.ExpiredSignatureError:
        exp_time = jwt.decode(
            token,
            options={"verify_signature": False},
            algorithms=["RS256"],
        ).get("exp", 0)
        expired_at = datetime.fromtimestamp(exp_time, tz=timezone.utc)
        raise RuntimeError(f"Token expired at {expired_at.isoformat()}")
    except jwt.InvalidTokenError as exc:
        raise RuntimeError(f"Token verification failed: {exc}") from exc

    return payload


claims = decode_token_from_file()
print(f"Subject: {claims['sub']}, Issuer: {claims['iss']}")

Komut Satırından JWT Çözme

Bazen bir betik yazmadan terminaldeki bir token'a hızlıca göz atmak istersiniz. Belki bir OAuth akışında hata ayıklıyorsunuz ve Authorization başlığında ne olduğunu görmek istiyorsunuz ya da tarayıcı DevTools'undan bir token kopyalayıp son kullanma tarihini kontrol etmek istiyorsunuz. Python'ın -c bayrağı bunu tek satıra indirger. Token'ı pipe ile geçirin, biçimlendirilmiş JSON olarak iddiaları alın. Betik dosyasına gerek yok, sanal ortama gerek yok.

Bash
# JWT payload'ını panodan veya değişkenden çöz (doğrulamasız)
echo "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3JfOGYyYSIsInJvbGUiOiJhZG1pbiJ9.sig" \
  | python3 -c "
import sys, base64, json
token = sys.stdin.read().strip()
payload = token.split('.')[1]
payload += '=' * (-len(payload) % 4)
print(json.dumps(json.loads(base64.urlsafe_b64decode(payload)), indent=2))
"
# {
#   "sub": "usr_8f2a",
#   "role": "admin"
# }
Bash
# Algoritmayı ve anahtar kimliğini kontrol etmek için JWT başlığını çöz
echo "eyJhbGciOiJSUzI1NiIsImtpZCI6InNpZy0xNzI2In0.payload.sig" \
  | python3 -c "
import sys, base64, json
token = sys.stdin.read().strip()
header = token.split('.')[0]
header += '=' * (-len(header) % 4)
print(json.dumps(json.loads(base64.urlsafe_b64decode(header)), indent=2))
"
# {
#   "alg": "RS256",
#   "kid": "sig-1726"
# }
Bash
# PyJWT kuruluysa tek adımda doğrula ve çöz
python3 -c "
import jwt, sys, json
token = sys.argv[1]
payload = jwt.decode(token, options={'verify_signature': False}, algorithms=['HS256'])
print(json.dumps(payload, indent=2))
" "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3JfOGYyYSJ9.sig"

Terminal kurulumu olmadan görsel bir alternatif için token'ınızı ToolDeck JWT Çözücü'ye yapıştırın ve başlığı, payload'ı ve imza doğrulama durumunu anında görün.

python-jose ve Diğer Alternatifler

python-jose JWS, JWE (şifreli tokenlar) ve JWK'yi yerel olarak destekleyen alternatif bir JWT kütüphanesidir. Uygulamanızın şifreli JWT'leri (JWE) işlemesi gerekiyorsa — payload'ın yalnızca imzalanmadığı, şifrelendiği durumlarda — python-jose doğru seçimdir; çünkü PyJWT JWE'yi hiç desteklemez. Kütüphanenin ayrıca yerleşik JWKS anahtar seti desteği bulunur; bu da dönen anahtar setlerini sunan Auth0, Okta veya Keycloak gibi kimlik sağlayıcılarla entegrasyonu kolaylaştırır. Decode arayüzü PyJWT'ye neredeyse aynıdır, bu yüzden aralarında geçiş minimum kod değişikliği gerektirir:

Python 3.10+ — python-jose
# pip install python-jose[cryptography]
from jose import jwt as jose_jwt

token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3JfOGYyYSIsInNjb3BlIjoib3JkZXJzOnJlYWQifQ.signature"

# Doğrulamalı çözme — PyJWT ile aynı kalıp
payload = jose_jwt.decode(
    token,
    "signing-secret-key",
    algorithms=["HS256"],
    audience="https://api.example.com",
)
print(payload)
# {'sub': 'usr_8f2a', 'scope': 'orders:read'}

# Doğrulamasız çözme
claims = jose_jwt.get_unverified_claims(token)
header = jose_jwt.get_unverified_header(token)
print(f"Algorithm: {header['alg']}, Subject: {claims['sub']}")

Tavsiyem: PyJWT ile başlayın. JWT kullanım senaryolarının %95'ini karşılar, en büyük topluluğa sahiptir ve API'si temizdir. JWE desteğine ihtiyaç duyarsanız veya JWKS desteğini tercih ederseniz python-jose'ye geçin. Belirtmeye değer üçüncü bir seçenek Authlib'dir; JWT işlemesini çok daha büyük bir OAuth/OIDC çerçevesinin içinde sunar. OAuth istemci akışları için zaten Authlib kullanıyorsanız, authlib.jose.jwt modülü ikinci bir JWT bağımlılığı eklemenizi engeller. Aksi takdirde, yalnızca token çözme için ağır bir bağımlılıktır.

Sözdizimi Vurgulamalı Terminal Çıktısı

Terminalde ham JWT iddialarını okumak hızlı kontroller için uygun olsa da, token payload'larını düzenli olarak hata ayıklarken (dahili bir kimlik doğrulama ağ geçidi geliştirirken bunu her gün yaptım) renkli çıktı gerçek bir fark yaratır. Dize değerleri, sayılar, boolean'lar ve null farklı renklerde görüntülenir; bu da her karakteri okumadan eksik bir izni veya yanlış son kullanma zaman damgasını bir bakışta fark etmenizi sağlar.

rich kütüphanesi (pip install rich), JSON dizesi veya Python sözlüğü alan ve bunu terminale tam sözdizimi vurgulamasıyla yazdıran bir print_json fonksiyonuna sahiptir. PyJWT ile birleştirerek iki satırlık bir JWT inceleme iş akışı oluşturabilirsiniz:

Python 3.10+ — rich terminal output
# pip install rich PyJWT
import jwt
from rich import print_json

token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3JfOGYyYSIsInJvbGUiOiJhZG1pbiIsInBlcm1pc3Npb25zIjpbIm9yZGVyczpyZWFkIiwicmVmdW5kczpjcmVhdGUiXSwiZXhwIjoxNzExODE1NjAwfQ.sig"

payload = jwt.decode(
    token,
    options={"verify_signature": False},
    algorithms=["HS256"]
)

# Terminalde renklendirilmiş, girintili JSON çıktısı
print_json(data=payload)
# {
#   "sub": "usr_8f2a",           ← dizeler yeşil renkte
#   "role": "admin",
#   "permissions": [
#     "orders:read",
#     "refunds:create"
#   ],
#   "exp": 1711815600            ← sayılar camgöbeği renkte
# }
Not:rich çıktısı ANSI kaçış kodları içerir. Dosyalara yazmayın veya API uç noktalarından döndürmeyin — yalnızca terminal görüntüleme içindir. Düz metin çıktısına ihtiyaç duyduğunuzda json.dumps() kullanın.

Büyük Token Gruplarıyla Çalışma

JWT token'ların kendisi küçüktür (genellikle 2 KB'ın altında), ancak bunları toplu işlediğiniz senaryolar vardır. Güvenlik olayının ardından denetim günlüğü analizi. Kimlik doğrulama sağlayıcısı değişikliğinde oturum geçiş betikleri. Son 90 günde verilen her token'ın doğru anahtarla imzalandığını kanıtlamanız gereken uyumluluk toplu doğrulaması. Bir NDJSON günlük dosyasında on binlerce token varsa, satır satır işlemek tüm dosyayı belleğe yüklemekten kaçınır ve sonuçları aşamalı olarak raporlamanızı sağlar.

Denetim Günlüğünden Token'ları Toplu Doğrulama

Python 3.10+ — streaming token validation
import jwt
import json
from pathlib import Path

SECRET_KEY = "audit-log-signing-key"

def validate_token_log(log_path: str) -> dict:
    """Her satırda 'token' alanı bulunan bir NDJSON dosyasını işle.
    Geçerli, süresi dolmuş ve geçersiz token sayılarını döndürür.
    """
    stats = {"valid": 0, "expired": 0, "invalid": 0}

    with open(log_path) as fh:
        for line_num, line in enumerate(fh, 1):
            line = line.strip()
            if not line:
                continue

            try:
                record = json.loads(line)
                token = record["token"]
            except (json.JSONDecodeError, KeyError):
                stats["invalid"] += 1
                continue

            try:
                jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
                stats["valid"] += 1
            except jwt.ExpiredSignatureError:
                stats["expired"] += 1
            except jwt.InvalidTokenError:
                stats["invalid"] += 1

    return stats


result = validate_token_log("auth-events-2026-03.ndjson")
print(f"Valid: {result['valid']}, Expired: {result['expired']}, Invalid: {result['invalid']}")
# Valid: 14832, Expired: 291, Invalid: 17

NDJSON Token Dışa Aktarımından İddiaları Ayıklama

Python 3.10+ — extract and transform claims from token log
import base64
import json
from datetime import datetime, timezone

def extract_claims_stream(input_path: str, output_path: str):
    """Token'ları satır satır oku, payload'ları çöz, düzleştirilmiş iddiaları yaz."""
    with open(input_path) as infile, open(output_path, "w") as outfile:
        for line in infile:
            line = line.strip()
            if not line:
                continue

            record = json.loads(line)
            token = record.get("access_token", "")
            parts = token.split(".")
            if len(parts) != 3:
                continue

            payload_b64 = parts[1] + "=" * (-len(parts[1]) % 4)
            claims = json.loads(base64.urlsafe_b64decode(payload_b64))

            # Denetim dostu bir kayda düzleştir
            flat = {
                "timestamp": record.get("timestamp"),
                "subject": claims.get("sub"),
                "issuer": claims.get("iss"),
                "expired_at": datetime.fromtimestamp(
                    claims.get("exp", 0), tz=timezone.utc
                ).isoformat(),
            }
            outfile.write(json.dumps(flat) + "\n")

extract_claims_stream("token-audit.ndjson", "claims-extract.ndjson")
Not:Birkaç yüz MB'ın altındaki dosyalar için satır satır okuma yeterince verimlidir. Çok büyük token dökümlerinde performans sınırlarına ulaşırsanız, her token bağımsız olduğundan doğrulamayı çekirdekler arasında dağıtmak için multiprocessing.Pool kullanmayı düşünün.

Yaygın Hatalar

Bu dört hata, kod incelemelerinde ve Stack Overflow sorularında tekrar tekrar karşımıza çıkar. Her biri yapması kolaydır ve PyJWT'nin verdiği hata mesajı her zaman doğrudan nedene işaret etmez. Paket isimlendirme sorununu tek başına, birinin yanlış kütüphaneyi kurarak tamamen beklenmedik bir API ile karşılaştığında saatlerce hata ayıklama süresini harcadığına bizzat şahit oldum.

PyJWT ile python-jwt paket isimlerini karıştırma

Sorun: pip install jwt veya pip install python-jwt çalıştırmak tamamen farklı bir paket kurar. import jwt daha sonra başarısız olur ya da tanımadığınız bir API verir.

Çözüm: Her zaman pip install PyJWT ile kurun. Import şudur: import jwt. Doğru paketi onaylamak için pip show PyJWT ile kontrol edin.

Before · Python
After · Python
pip install jwt
# veya
pip install python-jwt

import jwt  # yanlış paket — tamamen farklı API
pip install PyJWT

import jwt  # doğru — bu PyJWT
print(jwt.__version__)  # 2.x
algorithms parametresini atlamak

Sorun: PyJWT 1.x'te algorithms isteğe bağlıydı ve herhangi bir algoritmaya izin veriyordu. Bu, saldırganın alg: none ayarlayabileceği bir güvenlik açığı oluşturuyordu. PyJWT 2.x artık algorithms eksikse DecodeError fırlatır.

Çözüm: algorithms parametresini her zaman açık bir liste olarak geçin. Yalnızca uygulamanızın gerçekten token ürettiği algoritmaları kullanın.

Before · Python
After · Python
# PyJWT 2.x — bu DecodeError fırlatır
payload = jwt.decode(token, SECRET_KEY)
# DecodeError: algorithms must be specified
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
RS256 için jwt.decode()'u yanlış anahtar türüyle kullanmak

Sorun: algorithms=["RS256"] ile jwt.decode()'a string gizli anahtar geçmek InvalidSignatureError fırlatır. RS256, paylaşılan gizli bir string değil, PEM kodlu açık anahtar gerektirir.

Çözüm: PEM açık anahtarını bir dosyadan veya ortam değişkeninden yükleyin. cryptography paketini kurun: pip install PyJWT cryptography.

Before · Python
After · Python
# Bu başarısız olur — RS256 açık anahtar gerektirir, string secret değil
payload = jwt.decode(token, "my-secret", algorithms=["RS256"])
# InvalidSignatureError
public_key = open("public_key.pem").read()
payload = jwt.decode(token, public_key, algorithms=["RS256"])
Manuel çözmede base64 dolgusunu unutmak

Sorun: JWT base64url kodlaması sondaki = karakterlerini atar. Python'ın base64.urlsafe_b64decode fonksiyonu, ham segmenti dolgu düzeltmesi yapmadan geçirirseniz binascii.Error: Incorrect padding fırlatır.

Çözüm: Çözmeden önce dolgu ekleyin: segment += '=' * (-len(segment) % 4). Bu formül her zaman doğru sayıda dolgu karakterini (0, 1, 2 veya 3) üretir.

Before · Python
After · Python
import base64
payload_b64 = token.split(".")[1]
data = base64.urlsafe_b64decode(payload_b64)
# binascii.Error: Incorrect padding
import base64
payload_b64 = token.split(".")[1]
payload_b64 += "=" * (-len(payload_b64) % 4)
data = base64.urlsafe_b64decode(payload_b64)  # çalışır

PyJWT ve Alternatifler — Hızlı Karşılaştırma

Yöntem
İmzayı Doğrular
İddiaları Doğrular
Özel Türler
Kurulum Gerektirir
PyJWT jwt.decode()
✓ (exp, aud, iss, nbf)
Yok (dict döndürür)
pip install PyJWT
PyJWT doğrulamasız çözme
Yok
pip install PyJWT
Manuel base64 çözme
Yok
Hayır (stdlib)
python-jose jwt.decode()
Yok
pip install python-jose
Authlib jwt.decode()
Yok
pip install Authlib
PyJWT + cryptography
✓ (RSA/EC)
Yok
pip install PyJWT cryptography

PyJWT, çoğu Python uygulaması için doğru başlangıç noktasıdır. HMAC'ı ve (cryptography arka ucu ile) RSA ve EC imza doğrulamasını kapsar. JWE (şifreli tokenlar) gerekiyorsa python-jose veya Authlib'e geçin. Manuel base64 çözme hata ayıklama için çalışır ancak sıfır güvenlik garantisi sunar.

Her seçeneğe ne zaman başvurduğumu açıklayayım: HS256 veya RS256 doğrulaması yapan herhangi bir standart web servisi için PyJWT. Mimari şifreli token veya JWKS rotasyonu içeriyorsa python-jose. pip'in kullanılamadığı ortamlarda hızlı inceleme için manuel base64 (CI konteynerleri, kısıtlı üretim sunucuları, bağımlılıkları en aza indirmek istediğiniz AWS Lambda soğuk başlatmaları). Proje zaten OAuth istemci akışları için Authlib kullanıyorsa ve başka bir JWT kütüphanesi eklemek gereksiz olacaksa Authlib.

Kodsuz bir alternatif için herhangi bir token'ı JWT Çözücü'ye yapıştırın ve çözülmüş başlık ile payload'ı iddia doğrulama geri bildirimiyle görün.

Sıkça Sorulan Sorular

Python'da imzayı doğrulamadan JWT nasıl çözülür?

jwt.decode() fonksiyonuna options={"verify_signature": False} ve algorithms=["HS256"] parametrelerini geçin. Bu, imzayı kontrol etmeden payload sözlüğünü döndürür. Bunu yalnızca inceleme amacıyla kullanın — doğru açık anahtarı getirmeden önce iddiaları okumak veya geliştirme ortamında hata ayıklamak için. Herhangi bir şeye erişimi kısıtlayan token'larda doğrulamayı asla atlamayın.

Python
import jwt

token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfOGYyYSIsInJvbGUiOiJhZG1pbiJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"

payload = jwt.decode(
    token,
    options={"verify_signature": False},
    algorithms=["HS256"]
)
print(payload)
# {'sub': 'usr_8f2a', 'role': 'admin'}

PyJWT ile python-jwt arasındaki fark nedir?

PyJWT (pip install PyJWT, import jwt), aylık 80 milyonun üzerinde indirme ile Python için en popüler JWT kütüphanesidir. python-jwt (pip install python_jwt) ise farklı bir API yüzeyine sahip, çok daha az kullanılan ayrı bir kütüphanedir. Birinin kodunda import jwt görüyorsanız, PyJWT kullanıyordur. İsimlendirme kargaşası, PyPI paket adının (PyJWT) import adından (jwt) farklı olmasından kaynaklanır. Spesifik bir nedeniniz yoksa PyJWT ile devam edin.

Python'da RS256 ile JWT nasıl çözülür?

Hem PyJWT hem de cryptography arka ucunu kurun: pip install PyJWT cryptography. Ardından PEM kodlu açık anahtarı key argümanı olarak geçin ve algorithms=["RS256"] belirtin. PyJWT, RSA imza doğrulamasını cryptography kütüphanesine devreder. cryptography paketi kurulu değilse PyJWT, RSA veya EC algoritmalarını kullanmaya çalıştığınızda hata fırlatır.

Python
import jwt

public_key = open("public_key.pem").read()

payload = jwt.decode(
    token,
    public_key,
    algorithms=["RS256"],
    audience="https://api.example.com"
)

PyJWT neden ExpiredSignatureError fırlatıyor?

PyJWT, varsayılan olarak exp (son kullanma) iddiasını kontrol eder. Mevcut UTC zamanı exp zaman damgasını geçmişse jwt.ExpiredSignatureError fırlatır. leeway parametresiyle saat sapması toleransı ekleyebilirsiniz: jwt.decode(token, key, algorithms=["HS256"], leeway=timedelta(seconds=30)). Bu, 30 saniyelik bir tolerans sağlar. Son kullanma kontrolünü tamamen devre dışı bırakmak için (üretimde önerilmez) options={"verify_exp": False} geçin.

Python
import jwt
from datetime import timedelta

try:
    payload = jwt.decode(token, secret, algorithms=["HS256"], leeway=timedelta(seconds=30))
except jwt.ExpiredSignatureError:
    print("Token süresi doldu — yeniden kimlik doğrulama gerekli")

Python'da herhangi bir kütüphane kullanmadan JWT iddialarını okuyabilir miyim?

Evet. Token'ı noktalara göre bölün, ikinci segmenti (payload) alın, uzunluğu 4'ün katı olacak şekilde = karakterleriyle doldurun, ardından base64url ile çözün ve JSON'ı ayrıştırın. Bu, iddiaları sözlük olarak verir ancak imzayı doğrulamaz. PyJWT kuramadığınız kısıtlı ortamlarda veya hızlı hata ayıklama betiklerinde kullanışlıdır.

Python
import base64, json

token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3JfOGYyYSJ9.signature"
payload_b64 = token.split(".")[1]
payload_b64 += "=" * (-len(payload_b64) % 4)  # dolgu ekle
claims = json.loads(base64.urlsafe_b64decode(payload_b64))
print(claims)  # {'sub': 'usr_8f2a'}

PyJWT ile audience iddiası nasıl doğrulanır?

jwt.decode() fonksiyonuna audience parametresini geçin: jwt.decode(token, key, algorithms=["HS256"], audience="https://api.example.com"). PyJWT, token'daki aud iddiasını sağladığınız değerle karşılaştırır. Token'da aud iddiası yoksa veya değer eşleşmiyorsa jwt.InvalidAudienceError fırlatır. Servisiniz birden fazla API için token kabul ediyorsa kabul edilebilir audience'ların bir listesini de geçebilirsiniz.

Python
import jwt

payload = jwt.decode(
    token,
    secret,
    algorithms=["HS256"],
    audience=["https://api.example.com", "https://admin.example.com"]
)

İlgili Araçlar

DV
Dmitri VolkovDevOps Engineer & Python Automation Specialist

Dmitri is a DevOps engineer who relies on Python as his primary scripting and automation language. He builds internal tooling, CI/CD pipelines, and infrastructure automation scripts that run in production across distributed teams. He writes about the Python standard library, subprocess management, file processing, encoding utilities, and the practical shell-adjacent Python that DevOps engineers use every day.

MS
Maria SantosTeknik İnceleyici

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.