221 lines
6.0 KiB
JavaScript
221 lines
6.0 KiB
JavaScript
|
|
/**
|
|||
|
|
* 认证工具模块
|
|||
|
|
* 用于其他页面检查登录状态、获取用户信息、退出登录等
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
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<boolean>} 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<Object>} 响应数据
|
|||
|
|
*/
|
|||
|
|
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<Object|null>} 用户信息或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<boolean>} 是否更新成功
|
|||
|
|
*/
|
|||
|
|
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;
|
|||
|
|
}
|