/** * 认证工具模块 * 用于其他页面检查登录状态、获取用户信息、退出登录等 */ const AuthHelper = { // 配置常量 TOKEN_KEY: 'duoduo_auth_token', USER_INFO_KEY: 'duoduo_user_info', API_BASE_URL: 'http://192.168.1.17:8080/api', /** * 获取存储的token * @returns {string|null} token字符串或null */ getToken() { return localStorage.getItem(this.TOKEN_KEY); }, /** * 获取存储的用户信息 * @returns {Object|null} 用户信息对象或null */ getUserInfo() { const userInfo = localStorage.getItem(this.USER_INFO_KEY); return userInfo ? JSON.parse(userInfo) : null; }, /** * 检查是否已登录 * @returns {boolean} 是否已登录 */ isLoggedIn() { return !!this.getToken(); }, /** * 退出登录 * 清除所有认证信息并跳转到登录页 */ logout() { localStorage.removeItem(this.TOKEN_KEY); localStorage.removeItem(this.USER_INFO_KEY); window.location.href = 'auth.html'; }, /** * 验证token是否有效 * 调用后端API验证token,如果无效则清除登录状态 * @returns {Promise} token是否有效 */ async validateToken() { const token = this.getToken(); if (!token) { return false; } try { const response = await fetch(`${this.API_BASE_URL}/auth/me`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { const data = await response.json(); if (data.success) { // 更新用户信息 localStorage.setItem(this.USER_INFO_KEY, JSON.stringify(data.data)); return true; } } // Token无效,清除登录状态 this.logout(); return false; } catch (error) { console.error('Token验证失败:', error); return false; } }, /** * 路由守卫:保护需要登录的页面 * 如果未登录则跳转到登录页 * @param {string} redirectUrl 跳转的登录页URL,默认为auth.html * @returns {boolean} 是否已登录 */ requireAuth(redirectUrl = 'auth.html') { if (!this.isLoggedIn()) { window.location.href = redirectUrl; return false; } return true; }, /** * 获取带认证头的fetch配置 * @param {Object} options fetch的配置对象 * @returns {Object} 包含Authorization头的配置对象 */ getAuthHeaders(options = {}) { const token = this.getToken(); return { ...options, headers: { ...options.headers, 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }; }, /** * 发送认证请求的封装方法 * @param {string} url 请求URL * @param {Object} options fetch配置 * @returns {Promise} 响应数据 */ async fetchWithAuth(url, options = {}) { const response = await fetch(url, this.getAuthHeaders(options)); // 如果返回401未授权,清除登录状态并跳转 if (response.status === 401) { this.logout(); return null; } return response.json(); }, /** * 获取当前用户信息(从服务器获取最新) * @returns {Promise} 用户信息或null */ async getCurrentUser() { try { const data = await this.fetchWithAuth(`${this.API_BASE_URL}/auth/me`); if (data && data.success) { // 更新本地存储的用户信息 localStorage.setItem(this.USER_INFO_KEY, JSON.stringify(data.data)); return data.data; } return null; } catch (error) { console.error('获取用户信息失败:', error); return null; } }, /** * 更新用户资料 * @param {Object} profileData 要更新的资料数据 * @returns {Promise} 是否更新成功 */ async updateProfile(profileData) { try { const data = await this.fetchWithAuth(`${this.API_BASE_URL}/auth/profile`, { method: 'PUT', body: JSON.stringify(profileData) }); if (data && data.success) { // 更新成功后刷新用户信息 await this.getCurrentUser(); return true; } return false; } catch (error) { console.error('更新资料失败:', error); return false; } }, /** * 在页面中显示用户名 * @param {string} elementId 要显示用户名的元素ID */ displayUsername(elementId) { const userInfo = this.getUserInfo(); if (userInfo && userInfo.username) { const element = document.getElementById(elementId); if (element) { element.textContent = userInfo.username; } } }, /** * 在页面中显示用户完整信息 * @param {Object} elementIds 元素ID映射对象 {username: 'username-el', email: 'email-el', ...} */ displayUserInfo(elementIds) { const userInfo = this.getUserInfo(); if (!userInfo) return; for (const [field, elementId] of Object.entries(elementIds)) { const element = document.getElementById(elementId); if (element && userInfo[field]) { element.textContent = userInfo[field]; } } } }; // 如果在浏览器环境中,暴露到全局 if (typeof window !== 'undefined') { window.AuthHelper = AuthHelper; } // 支持ES6模块导出 if (typeof module !== 'undefined' && module.exports) { module.exports = AuthHelper; }