文件
Parlz/oauth_bind.php
T
2026-06-04 22:42:27 +08:00

325 行
14 KiB
PHP

<?php
session_start();
// 测试模式:如果没有OAuth信息,使用测试数据(方便直接访问测试UI)
$isTestMode = false;
$hasOAuthData = isset($_SESSION['oauth_provider']) && isset($_SESSION['oauth_user']);
if (!$hasOAuthData) {
// 优先使用URL参数指定平台,否则默认使用microsoft
$testProvider = $_GET['test'] ?? 'microsoft';
$isTestMode = true;
$_SESSION['oauth_provider'] = $testProvider;
$_SESSION['oauth_user'] = ['id' => 'test_id_123', 'username' => '测试用户', 'avatar' => ''];
}
// 记录调试信息
error_log("OAuth Bind - isTestMode: " . ($isTestMode ? 'true' : 'false') . ", provider: " . ($_SESSION['oauth_provider'] ?? 'null'));
$provider = $_SESSION['oauth_provider'];
$oauthUser = $_SESSION['oauth_user'];
// 平台信息配置
$providerConfig = [
'qq' => ['name' => 'QQ', 'icon' => 'fab fa-qq', 'class' => 'qq-login-btn', 'field' => 'qq_openid', 'color' => '#12B7F5'],
'github' => ['name' => 'GitHub', 'icon' => 'fab fa-github', 'class' => 'github-login-btn', 'field' => 'github_id', 'color' => '#333333'],
'microsoft' => ['name' => 'Microsoft', 'icon' => 'fab fa-microsoft', 'class' => 'microsoft-login-btn', 'field' => 'microsoft_id', 'color' => '#00A4EF'],
'steam' => ['name' => 'Steam', 'icon' => 'fab fa-steam', 'class' => 'steam-login-btn', 'field' => 'steam_id', 'color' => '#1B2838'],
'discord' => ['name' => 'Discord', 'icon' => 'fab fa-discord', 'class' => 'discord-login-btn', 'field' => 'discord_id', 'color' => '#5865F2']
];
$config = isset($providerConfig[$provider]) ? $providerConfig[$provider] : ['name' => '未知平台', 'icon' => 'fas fa-user', 'class' => 'qq-login-btn', 'field' => 'qq_openid', 'color' => '#333333'];
// 检测第三方账号是否已绑定(测试模式跳过)
if (!$isTestMode) {
try {
require_once 'db.php';
$db = Database::getInstance();
// 根据平台查询绑定的用户
$field = $config['field'];
error_log("OAuth Bind - Querying users table with field: $field, oauth_id: " . $oauthUser['id']);
$userResult = $db->query("SELECT id, username FROM users WHERE $field = :oauth_id", ['oauth_id' => $oauthUser['id']]);
error_log("OAuth Bind - Query result count: " . count($userResult ?? []));
if (!empty($userResult)) {
// 已绑定,直接登录
$user = $userResult[0];
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
// 更新最后登录时间
$db->execute("UPDATE users SET last_login = :time WHERE id = :id", ['time' => time(), 'id' => $user['id']]);
// 清除OAuth会话数据
unset($_SESSION['oauth_provider']);
unset($_SESSION['oauth_user']);
// 跳转到首页
error_log("OAuth Bind - User already bound, redirecting to index.php");
header('Location: index.php');
exit;
} else {
error_log("OAuth Bind - No existing user found, showing bind page");
}
} catch (Exception $e) {
error_log("OAuth Bind - Database error: " . $e->getMessage());
// 如果数据库出错,继续显示绑定页面而不是跳转
}
}
// 处理表单提交
$action = $_POST['action'] ?? '';
$error = '';
if ($_SERVER['REQUEST_METHOD'] == 'POST' && $action) {
require_once 'modules/user.php';
require_once 'db.php';
if ($action == 'bind') {
// 绑定已有账号
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
if (login($username, $password)) {
// 登录成功,绑定第三方账号
$userId = $_SESSION['user_id'];
$db = Database::getInstance();
// 更新用户信息,绑定第三方账号
$updateData = [
'id' => $userId,
'last_login' => time()
];
switch ($provider) {
case 'qq':
$updateData['qq_openid'] = $oauthUser['id'];
$updateData['qq_nickname'] = $oauthUser['username'];
if (!empty($oauthUser['avatar'])) {
$updateData['avatar'] = $oauthUser['avatar'];
}
break;
case 'github':
$updateData['github_id'] = $oauthUser['id'];
$updateData['github_username'] = $oauthUser['username'];
if (!empty($oauthUser['avatar'])) {
$updateData['avatar'] = $oauthUser['avatar'];
}
break;
case 'microsoft':
$updateData['microsoft_id'] = $oauthUser['id'];
$updateData['microsoft_username'] = $oauthUser['username'];
break;
case 'steam':
$updateData['steam_id'] = $oauthUser['id'];
$updateData['steam_username'] = $oauthUser['username'];
break;
case 'discord':
$updateData['discord_id'] = $oauthUser['id'];
$updateData['discord_username'] = $oauthUser['username'];
break;
}
// 构建更新SQL
$updateFields = [];
$params = [];
foreach ($updateData as $key => $value) {
$updateFields[] = "$key = :$key";
$params[$key] = $value;
}
$db->execute("UPDATE users SET " . implode(', ', $updateFields) . " WHERE id = :id", $params);
// 清除OAuth会话数据
unset($_SESSION['oauth_provider']);
unset($_SESSION['oauth_user']);
header('Location: index.php');
exit;
} else {
$error = 'username_or_password_error';
}
} elseif ($action == 'register') {
// 注册新账号并绑定
$username = $_POST['username'] ?? '';
$email = $_POST['email'] ?? '';
// 检查用户名是否已存在
$db = Database::getInstance();
$existing = $db->query("SELECT id FROM users WHERE username = :username", ['username' => $username]);
if (!empty($existing)) {
$error = 'username_exists';
} else {
// 创建新用户
$newId = generateId();
$currentTime = time();
$randomPassword = bin2hex(random_bytes(16));
$insertData = [
'id' => $newId,
'username' => $username,
'password' => password_hash($randomPassword, PASSWORD_DEFAULT),
'email' => $email,
'avatar' => $oauthUser['avatar'] ?? '',
'bio' => '',
'created_at' => $currentTime,
'last_login' => $currentTime
];
// 根据平台添加对应的字段
switch ($provider) {
case 'qq':
$insertData['qq_openid'] = $oauthUser['id'];
$insertData['qq_nickname'] = $oauthUser['username'];
break;
case 'github':
$insertData['github_id'] = $oauthUser['id'];
$insertData['github_username'] = $oauthUser['username'];
break;
case 'microsoft':
$insertData['microsoft_id'] = $oauthUser['id'];
$insertData['microsoft_username'] = $oauthUser['username'];
break;
case 'steam':
$insertData['steam_id'] = $oauthUser['id'];
$insertData['steam_username'] = $oauthUser['username'];
break;
case 'discord':
$insertData['discord_id'] = $oauthUser['id'];
$insertData['discord_username'] = $oauthUser['username'];
break;
}
// 构建插入SQL
$columns = implode(', ', array_keys($insertData));
$placeholders = ':' . implode(', :', array_keys($insertData));
$db->execute("INSERT INTO users ($columns) VALUES ($placeholders)", $insertData);
// 登录新用户
$_SESSION['user_id'] = $newId;
$_SESSION['username'] = $username;
// 清除OAuth会话数据
unset($_SESSION['oauth_provider']);
unset($_SESSION['oauth_user']);
header('Location: index.php');
exit;
}
}
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Parlz - 第三方账号绑定</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<div class="login-container">
<div class="login-box">
<h1 class="app-title">Parlz</h1>
<!-- 第三方账号信息 -->
<div class="oauth-info">
<div class="oauth-icon-wrapper">
<i class="<?php echo $config['icon']; ?>"></i>
</div>
<div class="oauth-text">
<div class="oauth-provider"><?php echo $config['name']; ?>账号</div>
<div class="oauth-username"><?php echo htmlspecialchars($oauthUser['username']); ?></div>
</div>
</div>
<div class="oauth-title">选择操作</div>
<div class="oauth-desc">您即将使用<?php echo $config['name']; ?>账号登录Parlz,请选择以下操作:</div>
<!-- 操作按钮 -->
<div class="oauth-actions">
<button class="oauth-action-btn oauth-register-btn" id="register-btn">
<i class="fas fa-user-plus"></i>
<span>注册新账号并绑定</span>
</button>
<button class="oauth-action-btn oauth-bind-btn" id="bind-btn">
<i class="fas fa-link"></i>
<span>绑定已有账号</span>
</button>
</div>
<!-- 绑定已有账号的登录表单 -->
<div id="login-form-section" class="oauth-form-section">
<h3>登录已有账号</h3>
<form id="bind-form" method="POST">
<input type="hidden" name="action" value="bind">
<div class="input-group">
<i class="fas fa-user"></i>
<input type="text" name="username" placeholder="用户名" required>
<span class="required-mark">*</span>
</div>
<div class="input-group">
<i class="fas fa-lock"></i>
<input type="password" name="password" placeholder="密码" required>
<span class="required-mark">*</span>
</div>
<button type="submit" name="bind" class="login-btn">绑定账号</button>
<?php if ($error === 'username_or_password_error'): ?>
<div class="error">用户名或密码错误</div>
<?php endif; ?>
</form>
</div>
<!-- 注册新账号的表单 -->
<div id="register-form-section" class="oauth-form-section">
<h3>创建新账号</h3>
<form id="register-form" method="POST">
<input type="hidden" name="action" value="register">
<div class="input-group">
<i class="fas fa-user"></i>
<input type="text" name="username" placeholder="用户名" required>
<span class="required-mark">*</span>
</div>
<div class="input-group">
<i class="fas fa-envelope"></i>
<input type="email" name="email" placeholder="邮箱(选填)">
</div>
<button type="submit" name="register" class="login-btn">创建账号</button>
<?php if ($error === 'username_exists'): ?>
<div class="error">用户名已存在</div>
<?php endif; ?>
</form>
</div>
<a href="index.php" class="oauth-back-link">返回登录页</a>
</div>
</div>
<script>
// 注册新账号按钮点击
document.getElementById('register-btn').addEventListener('click', function() {
document.getElementById('login-form-section').style.display = 'none';
document.getElementById('register-form-section').style.display = 'block';
});
// 绑定已有账号按钮点击
document.getElementById('bind-btn').addEventListener('click', function() {
document.getElementById('register-form-section').style.display = 'none';
document.getElementById('login-form-section').style.display = 'block';
});
// 显示错误对应的表单
<?php if ($error === 'username_or_password_error'): ?>
document.getElementById('login-form-section').style.display = 'block';
<?php elseif ($error === 'username_exists'): ?>
document.getElementById('register-form-section').style.display = 'block';
<?php endif; ?>
</script>
</body>
</html>