第57批续12: 修复token有效期误判+绑邮箱弹窗邮箱字段缺失

- core.php: validateWebAccess view操作不再要求web_login_verified——
  token 10分钟内有效即直接放行,在线玩家无需二次密码(之前逻辑要求
  Java推送web_login_verified才放行,导致自动注册token延期即失效)
- api/account.php: acctBindEmailPoll SQL补email字段——前端
  acctBindEmailCodeStep(d.email)拿不到邮箱,绑邮箱弹窗蒸发
This commit is contained in:
ypsdf1
2026-10-26 21:49:50 +08:00
parent d18f983b83
commit a33aba1b13
2 changed files with 5 additions and 19 deletions
+2 -1
View File
@@ -991,7 +991,7 @@ function acctBindEmailPoll() {
if ($id <= 0) error('缺少请求id'); if ($id <= 0) error('缺少请求id');
$db = getDB(); $db = getDB();
$stmt = $db->prepare("SELECT id, player_name, status, created_at, expire_at, approved_at, fail_reason FROM web_email_bind_requests WHERE id = :id"); $stmt = $db->prepare("SELECT id, player_name, email, status, created_at, expire_at, approved_at, fail_reason FROM web_email_bind_requests WHERE id = :id");
$stmt->bindValue(':id', $id, SQLITE3_INTEGER); $stmt->bindValue(':id', $id, SQLITE3_INTEGER);
$row = $stmt->execute()->fetchArray(SQLITE3_ASSOC); $row = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
if (!$row) error('请求不存在'); if (!$row) error('请求不存在');
@@ -1025,6 +1025,7 @@ function acctBindEmailPoll() {
'status' => $status, 'status' => $status,
'left' => $left, 'left' => $left,
'fail_reason' => (string)$row['fail_reason'], 'fail_reason' => (string)$row['fail_reason'],
'email' => (string)$row['email'],
], 'ok'); ], 'ok');
} }
+3 -18
View File
@@ -3445,7 +3445,7 @@ function validateWebAccess($webToken, $action = 'view', $password = null, $ipAdd
'ip' => $ipAddress 'ip' => $ipAddress
]); ]);
// 4. view操作:Token有效 + 在线 + Java推送web_login_verified → 允许访问 // 4. view操作:Token有效 + 在线 → 直接放行(token 10分钟内有效,不要求web_login_verified)
if ($action === 'view') { if ($action === 'view') {
if (!$isRegistered) { if (!$isRegistered) {
// ★ 玩家未在游戏中注册 → 允许Web注册,录入注册请求等待插件同步 // ★ 玩家未在游戏中注册 → 允许Web注册,录入注册请求等待插件同步
@@ -3457,24 +3457,9 @@ function validateWebAccess($webToken, $action = 'view', $password = null, $ipAdd
debugLog("validateWebAccess: 需要密码(不在线)", ['player' => $playerName]); debugLog("validateWebAccess: 需要密码(不在线)", ['player' => $playerName]);
return ['ok' => false, 'mode' => 'need_password', 'player' => $playerName, 'registered' => true, 'online' => false, 'message' => '请输入游戏登录密码以同步登录游戏']; return ['ok' => false, 'mode' => 'need_password', 'player' => $playerName, 'registered' => true, 'online' => false, 'message' => '请输入游戏登录密码以同步登录游戏'];
} }
// ★ 在线但未通过Java推送web_login_verified → 也需要密码(防止偷token自动登录) // ★ token有效+在线 → 直接放行(10分钟内有效,不需要web_login_verified)
$isWebVerified = false;
try {
// ★ 使用token的有效期作为窗口(而非硬编码5分钟),确保与token生命周期一致
$verifiedWindow = time() - $expireSeconds;
$wvStmt = $db->prepare("SELECT 1 FROM web_login_verified WHERE player_name = :player AND verified_at >= :expire");
$wvStmt->bindValue(':player', $playerName, SQLITE3_TEXT);
$wvStmt->bindValue(':expire', $verifiedWindow, SQLITE3_INTEGER);
$wvResult = $wvStmt->execute();
$wvRow = $wvResult->fetchArray();
if ($wvRow) $isWebVerified = true;
} catch (\Throwable $e) {}
if (!$isWebVerified) {
debugLog("validateWebAccess: 需要密码(在线但未验证)", ['player' => $playerName]);
return ['ok' => false, 'mode' => 'need_password', 'player' => $playerName, 'registered' => true, 'online' => true, 'message' => '请输入游戏登录密码以验证身份'];
}
$sessionToken = recordWebSession($playerName, $ipAddress); $sessionToken = recordWebSession($playerName, $ipAddress);
debugLog("validateWebAccess: 验证成功(Java已确认)", ['player' => $playerName, 'mode' => 'full']); debugLog("validateWebAccess: 验证成功(token有效)", ['player' => $playerName, 'mode' => 'full']);
return ['ok' => true, 'mode' => 'full', 'player' => $playerName, 'session' => $sessionToken, 'registered' => $isRegistered, 'online' => $isOnline, 'message' => '验证成功']; return ['ok' => true, 'mode' => 'full', 'player' => $playerName, 'session' => $sessionToken, 'registered' => $isRegistered, 'online' => $isOnline, 'message' => '验证成功'];
} }