本文へスキップ
ecdsa.com
jose (JavaScript)JWT ライブラリ

エラーメッセージ

Invalid Compact JWS

jose (JavaScript) — JWSInvalid, code ERR_JWS_INVALID

このエラーの意味

jose は、入力を JWS コンパクトシリアライゼーションの、ドットで区切られた 3 つのセグメント(header.payload.signature)に分割できませんでした。渡された文字列は構造上、署名付きトークンではありません。暗号処理は一切試みられていません。これは jsonwebtoken の「jwt malformed」に相当する jose のエラーで、それと同じく、問題は JWT ライブラリより前の段階、つまり文字列を生成または伝送した部分にあることを意味します。

発生する理由

修正方法

  1. 1.

    入力をサニタイズし、セグメント数を確認する

    jose を呼び出す前に、前後の空白を除去し、スキームを取り除き、セグメント数をアサートしてください。そうすれば、汎用的な解析エラーではなく、アプリケーション側で正確なエラーを出せます。

    js
    const token = raw.replace(/^Bearer\s+/i, "").trim();
    const segments = token.split(".").length;
    if (segments !== 3) throw new Error(`expected JWS (3 segments), got ${segments}`);
  2. 2.

    JWE トークンは復号処理に回す

    セグメントが 5 つあれば、そのトークンは暗号化されています。jwtVerify ではなく、受信者の秘密鍵を指定して jwtDecrypt を使ってください。

    js
    import { jwtDecrypt } from "jose";
    
    const { payload } = await jwtDecrypt(token, privateKey); // 5-segment JWE
  3. 3.

    文字列がどこで組み立てられたかを追跡する

    サニタイズした値でもまだ失敗する場合は、クライアント、ゲートウェイ、ストレージ、ハンドラーといった各経由地点で、値の長さと先頭の数文字をログに記録してください。署名付き JWT の最初のセグメントは base64url でエンコードされた JSON なので、本物のトークンは「eyJ」で始まります('{"' をエンコードした結果です)。これが成り立たなくなった地点で、値が壊れています。

    js
    console.log(token.length, JSON.stringify(token.slice(0, 12)));
    // healthy: 300+ 'eyJhbGciOiJF'

関連するエラー

署名エラーデータベースをすべて見る