🍪

HTTP通信でCookieが送られない理由と対処法【PHP/JavaScript】

に公開

問題:セッションが維持できない

WebAPIとの通信で「ログイン後のCookieが送られない」「セッションが切れる」という問題の原因は以下です。

ブラウザ以外のHTTPクライアントは、Cookieを自動送信しない


ブラウザとHTTPクライアントの違い

ブラウザの動作

  • Set-Cookieヘッダを自動保存
  • 次回リクエスト時に自動送信

HTTPクライアント(cURL/Guzzle/fetch等)の動作

  • Cookieの自動送信機能なし
  • セッションID(例:PHPSESSID)は手動管理が必要

対処法:各ライブラリごとの設定

PHP cURL

Cookie保存

curl_setopt($ch, CURLOPT_COOKIEJAR, __DIR__ . '/cookie.txt');

Cookie読み込み・送信

curl_setopt($ch, CURLOPT_COOKIEFILE, __DIR__ . '/cookie.txt');

Guzzle

CookieJarを使用

use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;

$jar = new CookieJar();
$client = new Client(['cookies' => $jar]);

同じ$clientインスタンスを使えば、Cookieが自動的に共有されます。


Laravel HTTP Client

Laravel のHttpファサード(Guzzleのラッパー)は、Cookieの自動処理を行いません。

手動でCookieヘッダを指定

Http::withHeaders([
    'Cookie' => 'PHPSESSID=abc123',
])->get('https://example.com');

またはGuzzle Clientを直接使用

use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;

$jar = new CookieJar();
$client = new Client(['cookies' => $jar]);

JavaScript fetch()

credentialsオプションを指定

fetch("/api/me", {
    credentials: "include"  // 同一オリジンのCookieを送信
});

※ デフォルトはcredentials: "omit"(送信しない)
※ クロスドメインの場合はCORS設定も必要


Cookieが送信されているか確認する方法

確認方法の一例として、リクエスト先で受信したCookieとセッションIDを比較する方法があります。

// api.php(リクエスト先)
session_start();

// 受信したCookie
echo "受信Cookie: " . ($_COOKIE['PHPSESSID'] ?? 'なし') . PHP_EOL;

// サーバー側のセッションID
echo "セッションID: " . session_id() . PHP_EOL;

// 両者が一致していればCookieが正しく送信されている

まとめ

ライブラリ Cookie送信方法
cURL COOKIEJAR / COOKIEFILE
Guzzle CookieJar
Laravel HTTP Cookieヘッダ手動指定 or Guzzle併用
fetch() credentials: "include"

セッションが維持できない場合は、上記の方法で リクエスト元とリクエスト先のセッションIDが一致しているか を確認しましょう。

Discussion