Files
CFDivePlatform/public/google-login-test.html
T
2025-05-11 03:45:17 +08:00

232 lines
9.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CFDive平台 - Google登入測試</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.container { max-width: 800px; margin-top: 50px; }
.card { margin-bottom: 20px; }
pre { background-color: #f8f9fa; padding: 15px; border-radius: 5px; max-height: 300px; overflow: auto; }
.btn-google { background-color: #4285F4; color: white; }
.hidden { display: none; }
</style>
</head>
<body>
<div class="container">
<h1 class="mb-4">CFDive平台 - Google登入測試</h1>
<!-- 登入卡片 -->
<div class="card">
<div class="card-header">
會員登入選項
</div>
<div class="card-body">
<h5 class="card-title">選擇登入方式</h5>
<p class="card-text">您可以使用以下方式登入系統:</p>
<!-- Google登入按鈕 -->
<a href="/api/auth/google/redirect" class="btn btn-google mb-3">
<i class="bi bi-google"></i> 使用Google帳號登入
</a>
<!-- 一般登入表單 -->
<div class="mt-4">
<h6>或使用電子郵件登入</h6>
<form id="loginForm" class="mt-3">
<div class="mb-3">
<label for="email" class="form-label">電子郵件</label>
<input type="email" class="form-control" id="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">密碼</label>
<input type="password" class="form-control" id="password" required>
</div>
<button type="submit" class="btn btn-primary">登入</button>
</form>
</div>
</div>
</div>
<!-- Token顯示區域 -->
<div id="tokenCard" class="card hidden">
<div class="card-header">
授權Token
</div>
<div class="card-body">
<h5 class="card-title">登入成功</h5>
<p class="card-text">您已成功登入系統,可以使用以下token進行API測試:</p>
<pre id="tokenInfo"></pre>
<button id="copyToken" class="btn btn-sm btn-secondary">複製Token</button>
</div>
</div>
<!-- API測試區域 -->
<div id="apiTestCard" class="card hidden">
<div class="card-header">
API測試
</div>
<div class="card-body">
<h5 class="card-title">測試會員API</h5>
<p class="card-text">使用您的授權token測試以下API</p>
<div class="mb-3">
<button id="getProfile" class="btn btn-info">獲取個人資料</button>
<button id="updateProfile" class="btn btn-warning">更新個人資料</button>
<button id="logout" class="btn btn-danger">登出</button>
</div>
<h6 class="mt-4">API回應結果:</h6>
<pre id="apiResponse">尚未執行API請求</pre>
</div>
</div>
</div>
<script>
// 檢查URL參數,處理登入後的回調
document.addEventListener('DOMContentLoaded', function() {
// 檢查URL是否包含登入成功的資訊
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('login_success')) {
try {
// 從localStorage獲取用戶資訊
const userInfo = JSON.parse(localStorage.getItem('user_info'));
if (userInfo && userInfo.token) {
showTokenInfo(userInfo);
}
} catch (e) {
console.error('無法解析用戶資訊', e);
}
}
// 檢查URL是否包含完整的用戶資訊(從callback獲取)
const hashParams = new URLSearchParams(window.location.hash.substring(1));
if (hashParams.has('user_info')) {
try {
const userInfo = JSON.parse(decodeURIComponent(hashParams.get('user_info')));
if (userInfo && userInfo.token) {
// 儲存到localStorage以便重新整理後仍可使用
localStorage.setItem('user_info', JSON.stringify(userInfo));
showTokenInfo(userInfo);
// 清除URL中的hash,避免重新整理後重複處理
history.replaceState(null, document.title, window.location.pathname + '?login_success=true');
}
} catch (e) {
console.error('無法解析用戶資訊', e);
}
}
});
// 一般登入表單處理
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
fetch('/api/member/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, password })
})
.then(response => response.json())
.then(data => {
if (data.status && data.data && data.data.token) {
const userInfo = {
user: data.data.user,
token: data.data.token,
token_type: data.data.token_type
};
localStorage.setItem('user_info', JSON.stringify(userInfo));
showTokenInfo(userInfo);
} else {
alert('登入失敗:' + (data.message || '未知錯誤'));
}
})
.catch(error => {
console.error('登入錯誤', error);
alert('登入過程發生錯誤,請檢查網路連線');
});
});
// 顯示Token資訊
function showTokenInfo(userInfo) {
document.getElementById('tokenCard').classList.remove('hidden');
document.getElementById('apiTestCard').classList.remove('hidden');
const tokenInfo = document.getElementById('tokenInfo');
tokenInfo.textContent = JSON.stringify(userInfo, null, 2);
// 設定複製按鈕功能
document.getElementById('copyToken').addEventListener('click', function() {
navigator.clipboard.writeText(userInfo.token)
.then(() => alert('Token已複製到剪貼簿'))
.catch(err => console.error('複製失敗', err));
});
// 設定API測試按鈕
setupApiButtons(userInfo.token);
}
// 設定API測試按鈕
function setupApiButtons(token) {
// 獲取個人資料
document.getElementById('getProfile').addEventListener('click', function() {
callApi('/api/member/profile', 'GET', null, token);
});
// 更新個人資料
document.getElementById('updateProfile').addEventListener('click', function() {
const newName = prompt('請輸入新的姓名', '');
if (newName) {
callApi('/api/member/profile', 'PUT', { name: newName }, token);
}
});
// 登出
document.getElementById('logout').addEventListener('click', function() {
callApi('/api/member/logout', 'POST', null, token)
.then(() => {
localStorage.removeItem('user_info');
document.getElementById('tokenCard').classList.add('hidden');
document.getElementById('apiTestCard').classList.add('hidden');
alert('已成功登出');
});
});
}
// 呼叫API
function callApi(url, method, data, token) {
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
const options = {
method: method,
headers: headers
};
if (data && (method === 'POST' || method === 'PUT')) {
options.body = JSON.stringify(data);
}
return fetch(url, options)
.then(response => response.json())
.then(data => {
document.getElementById('apiResponse').textContent = JSON.stringify(data, null, 2);
return data;
})
.catch(error => {
console.error('API錯誤', error);
document.getElementById('apiResponse').textContent = `錯誤: ${error.message}`;
});
}
</script>
</body>
</html>