🍪
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