API呼び出しをデバッグしているのに、HTTPクライアントが419を返します。公式IANAレジストリを確認 — そこにはありません。MDNで検索 — なし。HTTP 419とは何か、なぜサーバーがそれを送信しているのか?
短い答え
HTTP 419は公式のHTTPステータスコードではありません。 どのRFCでも定義されておらず、IANAに登録されていません。特定のフレームワークで使用されるカスタムステータスコードです — 特にLaravel(PHP) — が、CSRFトークンが期限切れまたは欠落していることを示すために使用します。
419が表示される場合、リクエストは:
- CSRFトークンをまったく含んでいなかったか、
- 期限切れのCSRFトークンが含まれていたか(Laravelのデフォルトは120分)、
- リクエスト間でセッションCookieが失われたか
HTTP 419の由来
Laravelは例外ハンドラでこのステータスコードを定義しています。POST、PUT、PATCH、またはDELETEリクエストがVerifyCsrfTokenミドルウェアで保護されたルートに到達し、トークンが無効な場合、Laravelは次のように応答します:
HTTP/1.1 419 Page Expired
「Page Expired」テキストは419のデフォルトのLaravel理由フレーズです。ページを説明しているのではなく、ページのCSRFトークンが結びついていたセッション状態を説明しています。
419を使用する他のフレームワーク
Laravelが最も一般的なソースですが、他のPHPフレームワークやカスタムAPIも同様の「セッション/トークン期限切れ」セマンティクスのために419を採用しています。PHPエコシステムにおける事実上の規約であり、普遍的な基準ではありません。
HTTP 419の修正方法
Laravelアプリを構築している場合
ブラウザフォーム(従来のレンダリング):
最も一般的な原因はセッションタイムアウトです。ユーザーがフォームを開き、2時間離れてから送信します。CSRFトークンはページの読み込み時に有効でしたが、それ以降セッションが期限切れになりました。
解決策:
- セッションの有効期間を延長
config/session.phpで:
// デフォルトは120分
'lifetime' => 480, // 8時間
- クライアントサイドのトークン更新を追加 — ページ読み込み時に、新しいCSRFトークンを取得するための軽量AJAXリクエストを行います:
<meta name="csrf-token" content="{{ csrf_token() }}">
// 30分ごとにトークンを更新
setInterval(() => {
fetch('/api/csrf-token', {
headers: { 'X-Requested-With': 'XMLHttpRequest' }
}).then(r => r.json()).then(data => {
document.querySelector('meta[name="csrf-token"]').content = data.token;
});
}, 30 * 60 * 1000);
- クライアントで419を优雅に処理 — 419応答をキャッチし、ログインにリダイレクトするかページをリロードします:
fetch('/api/save', { method: 'POST', body: formData })
.then(response => {
if (response.status === 419) {
// セッション期限切れ — 新しいトークンを取得するためにリロード
window.location.reload();
}
return response.json();
});
Laravel APIを消費している場合
モバイルアプリ、SPA、または外部サービスからLaravel APIを呼び出して419が返ってくる場合:
-
セッション/Cookieの処理を確認 APIはセッションCookieを期待している場合があります。HTTPクライアントがCookieを送受信していることを確認してください。
-
代わりにトークンベースの認証を使用 APIコンシューマーの場合、Laravel SanctumまたはLaravel Passportトークンは同じCSRF期限切れ問題を抱えません。セッションCookieの代わりに
Authorization: Bearer <token>ヘッダーを使用してください。 -
再認証 セッションが期限切れの場合、唯一の解決策は再びログインして新しいセッションを取得することです。
DevOps/インフラ担当者の場合
ロードバランサーやAPIゲートウェイのログで419が表示される場合:
- バックエンドがLaravelかどうかを確認 419はほぼ常にLaravel CSRFです。
- セッションストレージを確認 Redisまたはファイルベースのセッションストレージが満杯または設定が間違っている場合、セッションが早期に期限切れになる場合があります。
- クロック同期を確認 アプリケーションサーバーのクロックがずれている場合、セッション期限切れの計算がずれる場合があります。
HTTPステータスコードの確認方法
API応答をデバッグしていて、ステータスコードの意味をすばやく確認する必要がある場合は、リファレンスツールを使用できます。私たちのHTTPステータスコードリファレンスには、説明と検索機能付きのすべての63の公式コードが含まれています。
関連ステータスコード
| コード | 意味 | 関係 |
|---|---|---|
| 401 | Unauthorized | 認証トークンの欠落または無効 |
| 403 | Forbidden | 認証済みだが許可されていない |
| 408 | Request Timeout | サーバーがリクエストを待つ間にタイムアウト |
| 419 | Page Expired | CSRFトークン期限切れ(Laravel固有) |
| 440 | Login Timeout | 他のフレームワーク固有のバリアント |
| 503 | Service Unavailable | サーバーがダウンまたは過負荷 |
まとめ
HTTP 419は「セッションが期限切れ、このリクエストを信頼できない」とLaravelが伝えています。バグではなく、設計通りに機能しているセキュリティ機能です。解決策は、セッションの有効期間を延長するか、クライアントサイドでトークンを更新するか、プログラムアクセス用にAPIトークンに切り替えることです。