首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 跨域 Cookie 共享實戰:SameSite、Domain 屬性與安全最佳實踐

     編輯:PHP 綜合知識

場景描述

主域 a1.main.com(應用 A)需向子域 b1.test.com(應用 B)共享登錄態或用戶標識。本文詳細講解跨域 Cookie 設置的關鍵參數、瀏覽器同源策略限制、SameSite 屬性影響,並提供生產環境可用的完整解決方案。

核心代碼實現

應用 A(設置 Cookie 端)

<?php
// a1.main.com/main.php

// 1. 設置跨域 Cookie 關鍵參數
$cookieName = 'shared_token';
$cookieValue = 'user_12345_abcdef'; // 實際應為加密簽名的 Token
$expire = time() + 3600; // 1小時

// 關鍵設置解析:
setcookie($cookieName, $cookieValue, [
    'expires'  => $expire,
    'path'     => '/',                    // 整個域名路徑有效
    'domain'   => 'test.com',             // ★ 關鍵:設置為主域(不含子域前綴),所有子域共享
    'secure'   => true,                   // ★ 必須:HTTPS 環境下必須為 true
    'httponly' => true,                   // 防止 XSS 竊取(JS 無法讀取)
    'samesite' => 'None',                 // ★ 關鍵:允許跨站請求攜帶 Cookie
], $expire); // 兼容舊版 PHP 參數順序

// 兼容 PHP 7.3 以下版本的寫法
// setcookie($cookieName, $cookieValue, $expire, '/', 'test.com', true, true);
// 最後兩個參數:secure=true, httponly=true
// SameSite=None 需 PHP 7.3+ 或手動設置 header:
// header("Set-Cookie: {$cookieName}={$cookieValue}; expires=" . gmdate('D, d-M-Y H:i:s T', $expire) . "; path=/; domain=test.com; Secure; HttpOnly; SameSite=None");

應用 B(讀取 Cookie 端)

<?php
// b1.test.com/test.php

// 直接讀取 $_COOKIE 超全局變量
if (isset($_COOKIE['shared_token'])) {
    $token = $_COOKIE['shared_token'];
    echo "獲取到共享 Token: {$token}";
    
    // 驗證 Token 有效性(解密、檢查簽名、查詢 Redis 等)
    // $user = validateToken($token);
} else {
    echo "未獲取到共享 Cookie,可能原因:\n";
    echo "1. 用戶未訪問過 a1.main.com\n";
    echo "2. 瀏覽器阻止第三方 Cookie(隱私模式、設置)\n";
    echo "3. SameSite 策略攔截\n";
    echo "4. 域名設置不匹配\n";
}

關鍵參數深度解析

1. Domain 屬性:共享的核心

設置值作用範圍示例
未設置 / 當前域僅當前精確域名a1.main.com → 僅 a1.main.com
.main.com / main.com主域及所有子域main.com → a1.main.com, b2.main.com 等
test.comtest.com 及所有子域test.com → b1.test.com, api.test.com 等

規則: Domain 必須是當前域的父域或自身。a1.main.com 可設置 main.com,但不可設置 test.com(不同主域)。跨主域共享需通過 OAuth、JWT、或服務端同步會話實現。

2. SameSite 屬性:現代瀏覽器的攔截者

值行為跨域場景
Strict僅第一方請求攜帶(地址欄輸入、書籤)❌ 完全阻止
Lax(默認)第一方 + 安全頂級導航(鏈接跳轉、GET 表單)⚠️ 僅鏈接跳轉可用,AJAX/iframe 被阻
None所有請求攜帶(需配合 Secure)✅ 完全支持

關鍵限制: SameSite=None 必須 配合 Secure=true(HTTPS),否則瀏覽器會拒絕設置。

3. Secure + HttpOnly:安全基線

  • Secure:僅 HTTPS 傳輸,防止中間人竊取
  • HttpOnly:禁止 JavaScript 訪問(document.cookie),防禦 XSS
  • 兩者在生產環境必須同時開啟

完整流程圖解

用戶訪問 a1.main.com/main.php
       │
       ▼
服務端設置 Set-Cookie:
shared_token=xxx; Domain=test.com; Path=/; Secure; HttpOnly; SameSite=None
       │
       ▼
瀏覽器存儲 Cookie(域鍵:.test.com)
       │
       ▼
用戶點擊鏈接訪問 b1.test.com/test.php
       │
       ▼
瀏覽器自動攜帶 Cookie 發送請求
       │
       ▼
應用 B 讀取 $_COOKIE['shared_token'] → 驗證 → 識別用戶

常見問題排查清單

現象可能原因排查步驟
Cookie 未設置成功Domain 設置錯誤(非父域)檢查 Domain 值是否為當前域的父域
跨域請求未攜帶 CookieSameSite=Lax/Strict 攔截設置 SameSite=None + Secure=true
HTTPS 環境下仍失效證書不受信任/自簽名使用有效 CA 證書,瀏覽器無警告
隱私模式/無痕模式失效瀏覽器阻止第三方 Cookie引導用戶調整設置,或改用 OAuth/JWT
Safari/IE 兼容問題舊版瀏覽器不支持 SameSite=NoneUser-Agent 判斷降級策略,或棄用跨域 Cookie

現代替代方案:棄用跨域 Cookie

由於瀏覽器隱私策略收緊(ITP、第三方 Cookie 逐步淘汰),推薦採用:

方案一:JWT Token + Authorization Header

<?php
// 登錄後生成 JWT
$payload = ['uid' => 123, 'exp' => time() + 3600];
$jwt = JWT::encode($payload, $secretKey);

// 前端存儲在 localStorage/sessionStorage
// 跨域請求時手動添加 Header
fetch('https://b1.test.com/api', {
    headers: { 'Authorization': 'Bearer ' + jwt }
});

方案二:OAuth 2.0 / OpenID Connect

  • 統一認證中心(Keycloak、Auth0、自建)
  • 應用 A、B 為資源服務器,信任統一簽發的 Access Token
  • 支持單點登錄 (SSO)、單點登出 (SLO)

方案三:服務端會話同步(Redis 共享 Session)

<?php
// 兩應用配置相同的 Session 存儲
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://redis-server:6379?auth=password');
// 設置相同的 session.name 和 cookie.domain
ini_set('session.name', 'APP_SESSION');
ini_set('session.cookie_domain', '.test.com'); // 共享父域
// 同一用戶訪問任一應用,Session 即共享

總結建議

  1. 新項目:優先採用 JWT + Authorization Header 或 OAuth 2.0,避開 Cookie 限制
  2. 存量項目:確保 Domain=父域、SameSite=None、Secure=true、HttpOnly=true 四項全開
  3. 測試驗證:Chrome DevTools → Application → Cookies 檢查 Domain、SameSite、Secure 標記
  4. 降級預案:檢測 Cookie 失效時,引導用戶重新登錄或授權
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved