
本文介绍如何在 wordpress 主站与 laravel 子站之间安全、可靠地共享用户登录状态,通过跨子域 cookie 与 cors 配置,使主域名能实时感知子域名的登录状态并动态控制弹窗显示。
本文介绍如何在 wordpress 主站与 laravel 子站之间安全、可靠地共享用户登录状态,通过跨子域 cookie 与 cors 配置,使主域名能实时感知子域名的登录状态并动态控制弹窗显示。
在现代多系统协同架构中,主域名(如 example.com)运行 WordPress,而子域名(如 app.example.com)承载 Laravel 应用,两者需共享用户认证状态——这是常见但易出错的跨域场景。关键不在于“共享 Session 数据本身”,而在于让主站能可信地查询子站的登录状态。以下为完整、可落地的技术方案:
✅ 核心前提:Cookie 域名配置一致
Laravel 必须将 Session Cookie 的作用域设为顶级域名(含前导点),确保主站和子站均可携带同一凭证:
// config/session.php 'domain' => '.example.com', // 注意开头的点号,表示匹配所有子域 'secure' => true, // 生产环境务必启用 HTTPS 'http_only' => true, 'same_site' => 'lax',
同时确保 APP_URL 在 .env 中设为 https://app.example.com,避免 Laravel 重定向破坏 Cookie。
✅ Laravel 端:提供安全的登录状态接口
在 routes/web.php 中添加无 CSRF 保护的只读接口(因由前端 JS 调用,且仅返回布尔值):
// routes/web.php
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
Route::get('/check-login', function (Request $request) {
// 可选:校验 Referer 或 Origin 防止滥用(见下方注意事项)
$origin = $request->header('Origin');
if ($origin && !in_array($origin, ['https://example.com', 'https://www.example.com'])) {
return response()->json(['isLoggedIn' => false], 403);
}
return response()
->json(['isLoggedIn' => Auth::check()])
->withCookie(cookie()
->forever('laravel_session') // 确保响应 Cookie 不被覆盖
->domain('.example.com')
->httpOnly(false) // 允许 JS 读取(仅当需调试时;生产建议保持 true)
);
});⚠️ 重要 CORS 配置(在 app/Http/Middleware/Cors.php 或全局中间件中):
return $next($request)
->header('Access-Control-Allow-Origin', 'https://example.com')
->header('Access-Control-Allow-Credentials', 'true')
->header('Access-Control-Allow-Methods', 'GET')
->header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With');✅ WordPress 端:安全发起带凭据的 AJAX 请求
将以下代码保存为 wp-content/themes/your-theme/js/check-login.js,并在主题 functions.php 中正确加载(注意 in_footer => true 和 wp_enqueue_script 依赖声明):
document.addEventListener('DOMContentLoaded', function () {
// 使用 fetch 替代 jQuery(更轻量、现代标准)
fetch('https://app.example.com/check-login', {
method: 'GET',
credentials: 'include', // 关键:必须发送 cookies
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'application/json'
}
})
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.then(data => {
if (data.isLoggedIn === true) {
// ✅ 已登录:显示弹窗(示例使用原生 DOM 操作)
const popup = document.getElementById('login-popup');
if (popup) popup.style.display = 'block';
} else {
// ❌ 未登录:隐藏弹窗
const popup = document.getElementById('login-popup');
if (popup) popup.style.display = 'none';
}
})
.catch(err => {
console.warn('无法检查登录状态:', err.message);
// 网络失败时默认隐藏弹窗,保障用户体验
const popup = document.getElementById('login-popup');
if (popup) popup.style.display = 'none';
});
});⚠️ 安全与稳定性注意事项
-
HTTPS 强制要求:
withCredentials: true在非 HTTPS 下会被浏览器拒绝,主站与子站均需有效 SSL 证书。 -
避免 Cookie 冲突:WordPress 和 Laravel 的 Session Cookie 名称必须不同(默认
PHPSESSIDvslaravel_session),否则会相互覆盖。 -
缓存规避:在 Laravel 路由中添加
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]),并确保响应头包含Cache-Control: no-store, must-revalidate。 - 降级策略:AJAX 失败时应有明确 UI 回退(如默认隐藏弹窗),不可阻塞页面渲染。
- 性能优化:可在 WordPress 端增加节流(throttle)或 localStorage 缓存结果(有效期 60 秒),减少重复请求。
该方案不传输敏感数据,不共享 Session ID,仅通过受控接口返回布尔状态,兼顾安全性、兼容性与可维护性,是跨子域身份协同的推荐实践。

















