210 lines
8.5 KiB
PHP
210 lines
8.5 KiB
PHP
<?php
|
||
/**
|
||
* PHP Session配置检查和修复脚本
|
||
* 用于排查session跨请求丢失的问题
|
||
*/
|
||
|
||
error_reporting(E_ALL);
|
||
ini_set('display_errors', 1);
|
||
|
||
echo "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>Session配置检查</title>";
|
||
echo "<style>body{font-family: Arial, sans-serif; margin: 20px;} .ok{color: green;} .warning{color: orange;} .error{color: red;} table{border-collapse: collapse; width: 100%;} th,td{border: 1px solid #ddd; padding: 8px; text-align: left;} th{background-color: #f2f2f2;}</style>";
|
||
echo "</head><body>";
|
||
echo "<h1>PHP Session配置检查</h1>";
|
||
|
||
// 启动session
|
||
if (session_status() == PHP_SESSION_NONE) {
|
||
session_start();
|
||
}
|
||
|
||
echo "<h2>基本Session信息</h2>";
|
||
echo "<table>";
|
||
echo "<tr><th>项目</th><th>值</th><th>状态</th></tr>";
|
||
echo "<tr><td>Session ID</td><td>" . session_id() . "</td><td class='ok'>正常</td></tr>";
|
||
echo "<tr><td>Session 名称</td><td>" . session_name() . "</td><td class='ok'>正常</td></tr>";
|
||
echo "<tr><td>Session 状态</td><td>" . session_status() . " (" .
|
||
(session_status() == PHP_SESSION_DISABLED ? "已禁用" :
|
||
(session_status() == PHP_SESSION_NONE ? "未启动" : "已启动")) . ")</td><td class='" .
|
||
(session_status() == PHP_SESSION_ACTIVE ? "ok" : "error") . "'>" .
|
||
(session_status() == PHP_SESSION_ACTIVE ? "正常" : "异常") . "</td></tr>";
|
||
echo "</table>";
|
||
|
||
echo "<h2>Session配置检查</h2>";
|
||
echo "<table>";
|
||
echo "<tr><th>配置项</th><th>当前值</th><th>推荐值</th><th>状态</th><th>说明</th></tr>";
|
||
|
||
$configs = [
|
||
'session.save_handler' => ['推荐' => 'files', '说明' => 'Session存储方式'],
|
||
'session.save_path' => ['推荐' => '可写目录', '说明' => 'Session文件存储路径'],
|
||
'session.use_cookies' => ['推荐' => '1', '说明' => '使用Cookie存储Session ID'],
|
||
'session.use_only_cookies' => ['推荐' => '1', '说明' => '仅使用Cookie,不使用URL传递'],
|
||
'session.cookie_lifetime' => ['推荐' => '0', '说明' => 'Cookie生命周期,0表示浏览器关闭时删除'],
|
||
'session.cookie_path' => ['推荐' => '/', '说明' => 'Cookie作用路径'],
|
||
'session.cookie_domain' => ['推荐' => '', '说明' => 'Cookie作用域名'],
|
||
'session.cookie_secure' => ['推荐' => 'HTTPS时为1', '说明' => '仅在HTTPS下传输Cookie'],
|
||
'session.cookie_httponly' => ['推荐' => '1', '说明' => '防止JS访问Cookie'],
|
||
'session.gc_maxlifetime' => ['推荐' => '1440', '说明' => 'Session最大生存时间(秒)'],
|
||
'session.gc_probability' => ['推荐' => '1', '说明' => '垃圾回收概率分子'],
|
||
'session.gc_divisor' => ['推荐' => '100', '说明' => '垃圾回收概率分母']
|
||
];
|
||
|
||
foreach ($configs as $config => $info) {
|
||
$value = ini_get($config);
|
||
$status = 'ok';
|
||
$statusText = '正常';
|
||
|
||
// 特殊检查逻辑
|
||
switch ($config) {
|
||
case 'session.save_path':
|
||
if (empty($value)) {
|
||
$status = 'warning';
|
||
$statusText = '使用默认路径';
|
||
} elseif (!is_writable($value)) {
|
||
$status = 'error';
|
||
$statusText = '路径不可写';
|
||
}
|
||
break;
|
||
case 'session.use_cookies':
|
||
case 'session.use_only_cookies':
|
||
case 'session.cookie_httponly':
|
||
if ($value != '1') {
|
||
$status = 'warning';
|
||
$statusText = '建议启用';
|
||
}
|
||
break;
|
||
case 'session.cookie_secure':
|
||
$isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
|
||
if ($isHttps && $value != '1') {
|
||
$status = 'warning';
|
||
$statusText = 'HTTPS环境建议启用';
|
||
} elseif (!$isHttps && $value == '1') {
|
||
$status = 'error';
|
||
$statusText = 'HTTP环境不应启用';
|
||
}
|
||
break;
|
||
}
|
||
|
||
echo "<tr>";
|
||
echo "<td>$config</td>";
|
||
echo "<td>$value</td>";
|
||
echo "<td>" . $info['推荐'] . "</td>";
|
||
echo "<td class='$status'>$statusText</td>";
|
||
echo "<td>" . $info['说明'] . "</td>";
|
||
echo "</tr>";
|
||
}
|
||
echo "</table>";
|
||
|
||
echo "<h2>Session目录权限检查</h2>";
|
||
$savePath = ini_get('session.save_path');
|
||
if (empty($savePath)) {
|
||
$savePath = sys_get_temp_dir();
|
||
}
|
||
|
||
echo "<table>";
|
||
echo "<tr><th>项目</th><th>值</th><th>状态</th></tr>";
|
||
echo "<tr><td>Session保存路径</td><td>$savePath</td>";
|
||
if (is_dir($savePath)) {
|
||
echo "<td class='ok'>目录存在</td>";
|
||
} else {
|
||
echo "<td class='error'>目录不存在</td>";
|
||
}
|
||
echo "</tr>";
|
||
|
||
echo "<tr><td>目录可读</td><td>" . (is_readable($savePath) ? "是" : "否") . "</td>";
|
||
echo "<td class='" . (is_readable($savePath) ? "ok" : "error") . "'>" . (is_readable($savePath) ? "正常" : "异常") . "</td></tr>";
|
||
|
||
echo "<tr><td>目录可写</td><td>" . (is_writable($savePath) ? "是" : "否") . "</td>";
|
||
echo "<td class='" . (is_writable($savePath) ? "ok" : "error") . "'>" . (is_writable($savePath) ? "正常" : "异常") . "</td></tr>";
|
||
|
||
// 检查session文件
|
||
$sessionFile = $savePath . '/sess_' . session_id();
|
||
echo "<tr><td>Session文件</td><td>$sessionFile</td>";
|
||
if (file_exists($sessionFile)) {
|
||
echo "<td class='ok'>文件存在</td>";
|
||
} else {
|
||
echo "<td class='warning'>文件不存在</td>";
|
||
}
|
||
echo "</tr>";
|
||
|
||
if (file_exists($sessionFile)) {
|
||
echo "<tr><td>Session文件大小</td><td>" . filesize($sessionFile) . " 字节</td><td class='ok'>正常</td></tr>";
|
||
echo "<tr><td>Session文件修改时间</td><td>" . date('Y-m-d H:i:s', filemtime($sessionFile)) . "</td><td class='ok'>正常</td></tr>";
|
||
}
|
||
|
||
echo "</table>";
|
||
|
||
echo "<h2>环境信息</h2>";
|
||
echo "<table>";
|
||
echo "<tr><th>项目</th><th>值</th></tr>";
|
||
echo "<tr><td>PHP版本</td><td>" . PHP_VERSION . "</td></tr>";
|
||
echo "<tr><td>操作系统</td><td>" . PHP_OS . "</td></tr>";
|
||
echo "<tr><td>服务器软件</td><td>" . ($_SERVER['SERVER_SOFTWARE'] ?? '未知') . "</td></tr>";
|
||
echo "<tr><td>文档根目录</td><td>" . ($_SERVER['DOCUMENT_ROOT'] ?? '未知') . "</td></tr>";
|
||
echo "<tr><td>当前脚本</td><td>" . ($_SERVER['SCRIPT_NAME'] ?? '未知') . "</td></tr>";
|
||
echo "<tr><td>请求方法</td><td>" . ($_SERVER['REQUEST_METHOD'] ?? '未知') . "</td></tr>";
|
||
echo "<tr><td>User Agent</td><td>" . ($_SERVER['HTTP_USER_AGENT'] ?? '未知') . "</td></tr>";
|
||
echo "</table>";
|
||
|
||
echo "<h2>Cookie信息</h2>";
|
||
echo "<table>";
|
||
echo "<tr><th>Cookie名</th><th>值</th></tr>";
|
||
if (!empty($_COOKIE)) {
|
||
foreach ($_COOKIE as $name => $value) {
|
||
echo "<tr><td>$name</td><td>" . htmlspecialchars($value) . "</td></tr>";
|
||
}
|
||
} else {
|
||
echo "<tr><td colspan='2'>没有Cookie</td></tr>";
|
||
}
|
||
echo "</table>";
|
||
|
||
echo "<h2>修复建议</h2>";
|
||
echo "<div>";
|
||
|
||
// 检查常见问题并给出建议
|
||
$hasIssues = false;
|
||
|
||
if (!is_writable($savePath)) {
|
||
echo "<p class='error'>⚠️ Session保存目录不可写,需要修改目录权限</p>";
|
||
$hasIssues = true;
|
||
}
|
||
|
||
if (ini_get('session.use_cookies') != '1') {
|
||
echo "<p class='warning'>⚠️ 建议启用 session.use_cookies</p>";
|
||
$hasIssues = true;
|
||
}
|
||
|
||
if (ini_get('session.use_only_cookies') != '1') {
|
||
echo "<p class='warning'>⚠️ 建议启用 session.use_only_cookies</p>";
|
||
$hasIssues = true;
|
||
}
|
||
|
||
$isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
|
||
if ($isHttps && ini_get('session.cookie_secure') != '1') {
|
||
echo "<p class='warning'>⚠️ HTTPS环境建议启用 session.cookie_secure</p>";
|
||
$hasIssues = true;
|
||
}
|
||
|
||
if (!$hasIssues) {
|
||
echo "<p class='ok'>✅ 没有发现明显的配置问题</p>";
|
||
}
|
||
|
||
echo "<h3>微信登录相关建议:</h3>";
|
||
echo "<ul>";
|
||
echo "<li>确保浏览器支持Cookie并已启用</li>";
|
||
echo "<li>检查防火墙或代理是否阻止Cookie</li>";
|
||
echo "<li>确保微信授权回调的域名与设置Session的域名一致</li>";
|
||
echo "<li>检查服务器时间是否正确,避免Session过期</li>";
|
||
echo "<li>在nginx/apache配置中确保正确传递Cookie</li>";
|
||
echo "</ul>";
|
||
echo "</div>";
|
||
|
||
echo "<h2>测试工具</h2>";
|
||
echo "<p>";
|
||
echo "<a href='test_session_persistence.php' target='_blank' style='margin-right: 10px; padding: 5px 10px; background: #007cba; color: white; text-decoration: none;'>Session持久化测试</a>";
|
||
echo "<a href='test_weixin_session_flow.php' target='_blank' style='margin-right: 10px; padding: 5px 10px; background: #28a745; color: white; text-decoration: none;'>微信登录流程测试</a>";
|
||
echo "<a href='debug_weixin.php' target='_blank' style='margin-right: 10px; padding: 5px 10px; background: #17a2b8; color: white; text-decoration: none;'>微信登录调试</a>";
|
||
echo "</p>";
|
||
|
||
echo "</body></html>";
|
||
?>
|