エラーメッセージ
Not enough segments
別の表記
- jwt.exceptions.DecodeError: Not enough segments
PyJWT (Python) — jwt.exceptions.DecodeError
このエラーの意味
PyJWT は入力を `header.payload.signature` に分割できませんでした。含まれているドットが 2 つ未満です。この文字列はコンパクトな JWS ではないため、鍵もアルゴリズムも参照されていません。`jwt.decode()` に届いている値は JWT 以外の何か、または途中で末尾が失われた JWT です。
発生する理由
JWT ではなく不透明なアクセストークン
よくある多くの OAuth プロバイダーは、不透明なアクセストークン(Google の `ya29.…`、GitHub の `gho_…`)を発行します。これらはデコードするためのものではなく、イントロスペクションや userinfo を通じてプロバイダーに検証してもらうためのものです。JWT であることが保証されているのは、OpenID Connect の `id_token` だけです。
誤った変数をデコードしている
よくあるセッション ID、API キー、`str(None)`、またはフロントエンドから届いた文字列「undefined」などです。デコードの前に `repr(token)[:40]` をログに出力すれば、たいていはそれで原因がわかります。
トークンが途中で切れている
ときどき短すぎるデータベースのカラム、ログの行の長さ制限、途中で止まった手動のコピーによって、最後のセグメントとその前のドットが失われることがあります。
修正方法
- 1.
デコードの前に形を確認する
コンパクトな JWS には、ドットがちょうど 2 つあります。それ以外のものは API の入口で 401 を返して拒否し、不正な形式の入力がデコーダーに届かないようにしてください。
python def bearer_token(headers: dict) -> str | None: scheme, _, token = headers.get("Authorization", "").partition(" ") if scheme.lower() != "bearer" or token.count(".") != 2: return None # not a compact JWS: answer 401 instead of decoding return token - 2.
不透明なトークンは発行者に検証してもらう
プロバイダーが不透明なアクセストークンを発行する場合は、そのトークンイントロスペクションエンドポイント(RFC 7662)を呼び出すか、API 向けに JWT のアクセストークンを発行するようプロバイダーを設定してください(多くの場合、オーディエンスを指定してリクエストすることで設定できます)。
python import requests # Opaque tokens are validated by the authorization server (RFC 7662), not by decoding them. resp = requests.post( "https://issuer.example.com/oauth2/introspect", data={"token": token}, auth=(CLIENT_ID, CLIENT_SECRET), timeout=5, ) active = resp.json().get("active", False)