ホーム›AUTHENTICATION / HTTP

401 Unauthorizedの原因と直し方|認証ヘッダー・Cookieを切り分け

401は『権限がない』と即断するコードではなく、有効な認証情報が要求へ届いていない、または受け入れられなかった時の応答です。WWW-Authenticateとrequest IDを保存し、ブラウザー・API gateway・アプリのどこで認証が失われたかを成功要求との差分から絞ります。

先に結論

401は『権限がない』と即断するコードではなく、有効な認証情報が要求へ届いていない、または受け入れられなかった時の応答です。WWW-Authenticateとrequest IDを保存し、ブラウザー・API gateway・アプリのどこで認証が失われたかを成功要求との差分から絞ります。

認証をやり直す前に応答を保存する

  1. 対象URL、HTTP method、発生時刻、response status、request IDを保存する。
  2. WWW-Authenticateのschemeとパラメータを確認する。秘密値は記録しない。
  3. 全利用者か、特定アカウント・端末・API clientだけかを分ける。
  4. ブラウザー、CDN、API gateway、認証基盤、アプリのログを同じrequest IDと時刻でつなぐ。
  5. 同じURL・methodで成功した要求を一つ選び、送信された認証方式だけを比較する。
先に見る場所:全利用者で急に発生したなら認証基盤・鍵・gateway設定、特定clientだけならtoken取得条件・Cookie・Authorization転送を優先します。

発生条件から原因層を絞る

観測優先候補次の確認
全利用者・全APIで同時発生認証基盤、鍵、gateway障害情報、署名鍵、issuer、設定変更
特定clientだけtoken取得・保存・送信scheme、audience、scope、期限
ブラウザーだけCookie、SameSite、domainCookie送信有無、login redirect、HTTPS
APIだけAuthorization転送proxy・gateway前後のヘッダー有無
認証後は403認可・ロール403の権限・WAF切り分け
OPTIONSだけ失敗CORS・routepreflightの応答を確認

成功要求との差分を秘密値なしで比較する

  1. URL、method、hostname、経由したCDN/gatewayを揃える。
  2. 認証scheme、Cookie名、issuer、audience、scopeの有無を比較する。
  3. gatewayがAuthorizationを削除・上書きしていないかを確認する。
  4. 認証基盤の判定とアプリの判定をrequest IDで対応させる。
  5. 修正後は未認証、期限切れ、別ロールでも意図した401/403になるか確認する。

期限切れと時刻ずれを分ける

tokenの発行時刻・有効期限と、client、認証基盤、アプリのUTC時刻を比較します。時刻を手動で大きく動かすのではなく、標準の時刻同期状態と許容ずれを確認します。更新tokenが失敗した場合も、既存tokenをログやチャットへ貼らず、再発行経路のstatusとrequest IDを追います。

避ける操作

  • アクセストークン、session Cookie、API keyをログ・画面・外部サービスへ貼る。
  • 401を消すため認証middlewareやgateway認証を全停止する。
  • 全利用者のパスワードやtokenを原因未確認で一括失効する。
  • 認証エラーを200へ置換し、client側だけでアクセス制御する。
  • 401と403を同じものとして扱い、認証と認可のログを混ぜる。

公式情報

よくある質問

401と403の違いは何ですか?

401は有効な認証情報がないため要求を処理できない状態で、通常はWWW-Authenticateヘッダーで認証方法を示します。403は要求を理解したうえで拒否しており、同じ認証を繰り返しても解消しない場合があります。

ブラウザーでは開けるのにAPIだけ401になるのはなぜですか?

ブラウザーのCookie認証とAPIのAuthorizationヘッダーが別経路である、CORSやproxyがヘッダーを渡していない、tokenのaudienceやscopeが違うなどが候補です。成功要求と失敗要求を比較します。

tokenの中身をログへ残してよいですか?

アクセストークンやsession Cookieそのものは保存・共有しません。token種別、issuer、audience、scope、期限、request IDなど、秘密値を含まない属性だけを記録します。