本文へスキップ
ecdsa.com
express-jwt (Node.js)JWT ライブラリ

エラーメッセージ

UnauthorizedError: No authorization token was found

別の表記

  • No authorization token was found
  • Format is Authorization: Bearer [token]

エラーを処理しない場合、Express は「UnauthorizedError: No authorization token was found」で始まるエラーをスタックトレースとともに出力します。`err.code` を見ると、`credentials_required`(トークンなし)と、`credentials_bad_scheme` および `credentials_bad_format`(「Format is Authorization: Bearer [token]」)を区別できます。

express-jwt (Node.js) — UnauthorizedError, code credentials_required

このエラーの意味

express-jwt はルートを保護していますが、トークンを見つけられませんでした。リクエストに `Authorization` ヘッダーがなく、カスタムの `getToken` 関数もトークンを返しませんでした。`credentialsRequired` のデフォルトは `true` なので、ミドルウェアは `code: "credentials_required"` と `status: 401` を持つ `UnauthorizedError` を発生させ、リクエストはハンドラーに届きません。ヘッダーはあるものの `Bearer <token>` の形式になっていない場合は、代わりに「Format is Authorization: Bearer [token]」で失敗します。

発生する理由

修正方法

  1. 1.

    トークンの場所を express-jwt に伝える

    `getToken` はリクエストを受け取り、トークン文字列または `null` を返します。シンプルに保ち、複数の場所から同時にトークンを受け付けるのは避けてください。

    js
    import cookieParser from "cookie-parser";
    import { expressjwt } from "express-jwt";
    
    app.use(cookieParser());
    app.use(
      expressjwt({
        secret: getSigningKey,          // e.g. jwks-rsa's expressJwtSecret(...)
        algorithms: ["RS256"],
        getToken: (req) => req.cookies.access_token ?? null,
      }),
    );
  2. 2.

    公開ルートを除外するか、認証を任意にする

    `.unless()` は列挙したパスをスキップします。`credentialsRequired: false` にすると、トークンのないリクエストは `req.auth` なしで通過するため、ルートごとに判断できます。

    js
    app.use(
      expressjwt({ secret, algorithms: ["HS256"] }).unless({ path: ["/health", "/login", /^\/public\//] }),
    );
    
    // Or keep authentication optional and decide per route:
    app.use(expressjwt({ secret, algorithms: ["HS256"], credentialsRequired: false }));
  3. 3.

    エラーを適切な 401 に変換する

    Express のデフォルトのハンドラーはエラーの `status`(401)を使いますが、HTML ページ(開発環境ではスタックトレースを含む)で応答し、`WWW-Authenticate` ヘッダーを付けません。`UnauthorizedError` を、このヘッダーを付けた JSON の 401 に自分で変換してください。

    js
    app.use((err, req, res, next) => {
      if (err.name === "UnauthorizedError") {
        return res.status(401).set("WWW-Authenticate", "Bearer").json({ error: err.code });
      }
      next(err);
    });

関連するエラー

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