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

エラーメッセージ

missing required "aud" claim

別の表記

  • missing required "iss" claim
  • missing required "exp" claim
  • missing required "sub" claim
  • missing required "iat" claim

クレーム名は欠けているクレームに応じて変わります(`"aud"`、`"iss"`、`"exp"`、`"sub"`、`"iat"` など)。`err.claim` にその名前が入り、`err.reason` は `"missing"` になります。

jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED, reason "missing"

このエラーの意味

検証オプションで必須となるクレームが、トークンに含まれていません。jose がクレームを必須として扱うのは、`requiredClaims` に指定した場合だけではありません。そのクレームの確認を求めた場合も同様で、`audience` を指定すると `aud`、`issuer` では `iss`、`subject` では `sub`、`maxTokenAge` では `iat` が必須になります。引用符で囲まれたクレーム名から、どのクレームが欠けているかがわかります。署名はすでに有効と確認されています。

発生する理由

修正方法

  1. 1.

    欠けているクレームと存在するクレームをログに出力する

    エラーオブジェクトは `claim`、`reason`、デコード済みの `payload` を公開しています。これらをログに出力すれば、「発行者がそのクレームを書き込んでいない」のか「誤ったトークンが送られた」のかを、1 回のリクエストで判別できます。

    js
    import { errors, jwtVerify } from "jose";
    
    try {
      await jwtVerify(token, jwks, { algorithms: ["ES256"], audience: "https://api.example.com" });
    } catch (err) {
      if (err instanceof errors.JWTClaimValidationFailed && err.reason === "missing") {
        console.error("token lacks claim:", err.claim, "claims present:", Object.keys(err.payload));
      }
      throw err;
    }
  2. 2.

    発行者にクレームを含めてもらう

    検証者の条件を緩めるより、トークンを修正することを優先してください。JWT を安全に受け入れられるのは、`aud`、`iss`、`exp` があるからこそです。RFC 8725 は、すべてのトークンにこれらを含めることを推奨しています。

    js
    import { SignJWT } from "jose";
    
    const token = await new SignJWT({ scope: "orders:read" })
      .setProtectedHeader({ alg: "ES256", kid })
      .setIssuer("https://issuer.example.com")
      .setAudience("https://api.example.com")   // the claim the verifier requires
      .setIssuedAt()
      .setExpirationTime("10m")
      .sign(privateKey);

関連するエラー

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