「ログインは成功するのに
/api/meが500になる」
「Cookie送ってるのに未認証」
「キャッシュ消しても直らない」
この記事では、Reactと接続する前に Laravel だけで SPA認証を確認しようとした際に発生したエラーの記録をまとめています。
Laravel Sanctum の認証処理を curl で検証したところ、設定・コード・環境の3つの不整合が重なって動作しない状態に陥りました。
ここでは、その原因と解決までの手順を整理します。
概要:発生していた3つの問題
| 分類 | 内容 | 対応策 |
|---|---|---|
| コード |
$request->user()->id に直接アクセス → nullでクラッシュ |
nullチェックを追加し401を返すよう修正 |
| 設定 |
.env の SANCTUM_STATEFUL_DOMAINS に localhost:8000 が抜けていた |
localhostと5173ポートを明記 |
| 環境 | キャッシュやサーバープロセスが古い設定を保持 | artisan全クリア+サーバー再起動 |
検証の目的
Reactとつなぐ前に、以下の手順で Laravel 側の認証処理を確認しました。
-
/loginにメールアドレスとパスワードをPOSTしてセッション確立 - 取得したCookieを利用して
/api/meにアクセスし、ログイン中ユーザー情報を取得
このとき、次のようなエラーが発生しました。
-
419 unknown status(CSRF失敗) -
Empty reply from server(PHPクラッシュ) -
500 Internal Server Error(認証処理中にサーバー停止)
認証ルートとミドルウェアの設定
Laravelでは web.php は「セッションあり」、api.php は「セッションなし」を前提にしています。
Sanctum の SPA認証では Cookie を利用するため、APIルートにも web ミドルウェアを追加する必要があります。
// routes/api.php
Route::middleware(['api', 'web'])->group(function () {
Route::middleware('auth:sanctum')->get('/me', function (Request $request) {
if (!$request->user()) {
return response()->json(['message' => 'Unauthenticated.'], 401);
}
return response()->json([
'id' => $request->user()->id,
'email' => $request->user()->email,
'name' => $request->user()->name,
]);
});
});
これを設定しないと、Sanctum はセッション Cookie を認識できず、$request->user() は常に null のままになります。
CookieとSessionの関係
- Session: サーバー側でユーザーの状態を保持
- Session Cookie: クライアントに保存されるセッションID
クライアントはリクエストごとにCookieを送信し、サーバーは対応するセッションを復元して認証を継続します。
この動作を担うのが web ミドルウェアです。SPA認証ではこれが欠かせません。
CSRFトークンの取り扱い
Sanctum ではログイン前に /sanctum/csrf-cookie にアクセスし、XSRF-TOKEN Cookieを取得します。
その値をヘッダーで送信する必要があります。
curl -i -b cookie.txt -c cookie.txt -X POST \
-H "X-XSRF-TOKEN: eyJpdiI6InpFOW..." \
-d "email=test@example.com&password=password" \
http://localhost:8000/login
| エラー | 原因 | 対応 |
|---|---|---|
| 419 | フォームデータで送信していた | ヘッダー X-XSRF-TOKEN に変更 |
| Empty reply |
%3D がURLエンコードされたまま |
%3D → = にURLデコード |
| 500 |
$request->user() が null |
nullチェックを追加 |
500エラーの原因
ログから以下のエラーを確認しました。
[ERROR] Attempt to read property 'id' on null
Sanctum のセッションが認識されず $request->user() が null のままアクセスしていたため、Laravelがクラッシュしていました。
修正内容とリセット手順
routes/api.php
Route::middleware(['api', 'web'])->group(function () {
Route::middleware('auth:sanctum')->get('/me', fn (Request $r) =>
$r->user()
? response()->json(['id' => $r->user()->id])
: response()->json(['message' => 'Unauthenticated.'], 401)
);
});
.env
SANCTUM_STATEFUL_DOMAINS=localhost:5173,127.0.0.1:5173,localhost:8000,127.0.0.1:8000
キャッシュのクリア
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan cache:clear
php artisan clear-compiled
再起動と再ログイン
php artisan serve
rm cookie.txt
curl -X POST /login ...
curl -b cookie.txt http://localhost:8000/api/me
この手順で HTTP/1.1 200 OK が返るようになり、正常に認証情報を取得できました。
まとめと注意点
| 分類 | ポイント |
|---|---|
| 設定 |
SANCTUM_STATEFUL_DOMAINS にサーバー自身のドメインを含める |
| コード |
$request->user() の null チェックを追加 |
| 環境 | 変更後はサーバーを再起動しキャッシュをクリア |
| デバッグ |
Set-Cookie: が連続発行される場合はセッションが破棄されているサイン |
React接続前に Laravel 単体で認証を検証する際、この内容が同様の問題に直面している方の参考になれば幸いです。