Fehlermeldung
Signature has expired
PyJWT (Python) — jwt.exceptions.ExpiredSignatureError
Was der Fehler bedeutet
Der Claim exp des Tokens liegt vor der aktuellen Zeit der prüfenden Seite, deshalb hat PyJWT das Token nach einer (konzeptionell) erfolgreichen Signaturprüfung abgelehnt. Die Formulierung führt etwas in die Irre – nicht die Signatur selbst läuft ab, sondern das Gültigkeitsfenster des Tokens hat sich geschlossen.
Warum der Fehler auftritt
Veraltetes Token über seine Laufzeit hinaus wiederverwendet
häufigZwischengespeicherte Credentials in einem lang laufenden Worker, ein clientseitig gespeichertes Token, das nach Ablauf der TTL erneut gesendet wird, oder Integrationstests mit einem Fixture-Token, das vor Tagen erzeugt wurde. Die Ablehnung ist korrektes Verhalten.
Uhrenabweichung auf dem prüfenden Host
häufigGeht die Uhr der prüfenden Seite vor, verkürzt das die effektive Laufzeit jedes Tokens. Container und CI-Runner ohne Zeitsynchronisierung sind die üblichen Verdächtigen; schon 60–120 Sekunden Abweichung lassen kurzlebige Tokens sporadisch scheitern.
Der Aussteller schreibt exp falsch
gelegentlichexp muss ganzzahlige Sekunden seit der Epoche enthalten. Falsch serialisierte datetime-Objekte oder Millisekunden ergeben Tokens, die schon bei der Ausstellung abgelaufen sind – dann scheitert jede Prüfung sofort, und genau daran unterscheidet sich dieser Fall vom gewöhnlichen Ablauf.
exp aus einem datetime ohne Zeitzone erzeugt
gelegentlichAussteller, die exp aus datetime.now() (naive Ortszeit) statt aus datetime.now(timezone.utc) bilden, verschieben die Laufzeit jedes Tokens um den UTC-Offset des Servers. Je nachdem, auf welcher Seite von UTC der Aussteller liegt, laufen Tokens entweder Stunden zu früh ab oder überleben unbemerkt ihre vorgesehene TTL. PyJWT kodiert zeitzonenbewusste datetime-Objekte korrekt – die naiven sind die Falle.
So behebst du den Fehler
- 1.
Kleine Abweichungen mit leeway abfangen
Der Parameter leeway (in Sekunden) gilt für die Prüfungen von exp und nbf. Verwende höchstens einige Dutzend Sekunden; größere Werte verlängern die Laufzeit der Tokens unbemerkt.
python import jwt payload = jwt.decode( token, key, algorithms=["ES256"], leeway=30, # seconds of tolerated clock skew ) - 2.
Tatsächliche Zeitstempel untersuchen
Lies die Claims ohne Prüfung aus und vergleiche exp mit der Uhr des Hosts – an der Größe der Differenz erkennst du, ob es sich um einen Ablauf, eine Uhrenabweichung oder einen Fehler beim Ausstellen handelt.
python import jwt, time claims = jwt.decode(token, options={"verify_signature": False}) print("exp:", claims["exp"], "now:", int(time.time()), "delta:", int(time.time()) - claims["exp"], "s")