Files
AIEC-new/AIEC-server/utils/token/token-manager.js
2025-10-17 09:31:28 +08:00

262 lines
7.4 KiB
JavaScript
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.

/**
* Token管理工具类
*/
class TokenManager {
static TOKEN_KEY = 'yundage_token';
static USER_KEY = 'yundage_user';
static REFRESH_TOKEN_KEY = 'yundage_refresh_token';
/**
* 保存Token到本地存储
* @param {string} token - JWT Token
* @param {boolean} remember - 是否记住登录状态
*/
static saveToken(token, remember = false) {
try {
const storage = remember ? localStorage : sessionStorage;
storage.setItem(this.TOKEN_KEY, token);
// 解析token获取过期时间
const payload = this.parseToken(token);
if (payload && payload.exp) {
storage.setItem(this.TOKEN_KEY + '_exp', payload.exp.toString());
}
console.log('Token saved successfully');
} catch (error) {
console.error('Failed to save token:', error);
}
}
/**
* 获取Token
* @returns {string|null} Token或null
*/
static getToken() {
try {
// 优先从sessionStorage获取
let token = sessionStorage.getItem(this.TOKEN_KEY);
// 如果sessionStorage没有从localStorage获取
if (!token) {
token = localStorage.getItem(this.TOKEN_KEY);
}
// 检查token是否过期
if (token && this.isTokenExpired(token)) {
this.removeToken();
return null;
}
return token;
} catch (error) {
console.error('Failed to get token:', error);
return null;
}
}
/**
* 移除Token
*/
static removeToken() {
try {
sessionStorage.removeItem(this.TOKEN_KEY);
sessionStorage.removeItem(this.TOKEN_KEY + '_exp');
localStorage.removeItem(this.TOKEN_KEY);
localStorage.removeItem(this.TOKEN_KEY + '_exp');
// 同时清除用户信息
this.removeUser();
console.log('Token removed successfully');
} catch (error) {
console.error('Failed to remove token:', error);
}
}
/**
* 检查Token是否有效
* @returns {boolean} 是否有效
*/
static isTokenValid() {
const token = this.getToken();
return token !== null && !this.isTokenExpired(token);
}
/**
* 检查Token是否过期
* @param {string} token - JWT Token
* @returns {boolean} 是否过期
*/
static isTokenExpired(token) {
try {
const payload = this.parseToken(token);
if (!payload || !payload.exp) {
return true;
}
// JWT的exp是秒级时间戳JavaScript的Date.now()是毫秒级
const currentTime = Math.floor(Date.now() / 1000);
return payload.exp < currentTime;
} catch (error) {
console.error('Failed to check token expiration:', error);
return true;
}
}
/**
* 解析JWT Token
* @param {string} token - JWT Token
* @returns {object|null} 解析后的payload
*/
static parseToken(token) {
try {
const parts = token.split('.');
if (parts.length !== 3) {
throw new Error('Invalid token format');
}
const payload = parts[1];
const decoded = atob(payload.replace(/_/g, '/').replace(/-/g, '+'));
return JSON.parse(decoded);
} catch (error) {
console.error('Failed to parse token:', error);
return null;
}
}
/**
* 保存用户信息
* @param {object} user - 用户信息
* @param {boolean} remember - 是否记住登录状态
*/
static saveUser(user, remember = false) {
try {
const storage = remember ? localStorage : sessionStorage;
storage.setItem(this.USER_KEY, JSON.stringify(user));
console.log('User info saved successfully');
} catch (error) {
console.error('Failed to save user info:', error);
}
}
/**
* 获取用户信息
* @returns {object|null} 用户信息或null
*/
static getUser() {
try {
// 优先从sessionStorage获取
let userStr = sessionStorage.getItem(this.USER_KEY);
// 如果sessionStorage没有从localStorage获取
if (!userStr) {
userStr = localStorage.getItem(this.USER_KEY);
}
return userStr ? JSON.parse(userStr) : null;
} catch (error) {
console.error('Failed to get user info:', error);
return null;
}
}
/**
* 移除用户信息
*/
static removeUser() {
try {
sessionStorage.removeItem(this.USER_KEY);
localStorage.removeItem(this.USER_KEY);
console.log('User info removed successfully');
} catch (error) {
console.error('Failed to remove user info:', error);
}
}
/**
* 保存刷新Token
* @param {string} refreshToken - 刷新Token
*/
static saveRefreshToken(refreshToken) {
try {
localStorage.setItem(this.REFRESH_TOKEN_KEY, refreshToken);
} catch (error) {
console.error('Failed to save refresh token:', error);
}
}
/**
* 获取刷新Token
* @returns {string|null} 刷新Token或null
*/
static getRefreshToken() {
try {
return localStorage.getItem(this.REFRESH_TOKEN_KEY);
} catch (error) {
console.error('Failed to get refresh token:', error);
return null;
}
}
/**
* 移除刷新Token
*/
static removeRefreshToken() {
try {
localStorage.removeItem(this.REFRESH_TOKEN_KEY);
} catch (error) {
console.error('Failed to remove refresh token:', error);
}
}
/**
* 清除所有认证信息
*/
static clearAll() {
this.removeToken();
this.removeUser();
this.removeRefreshToken();
console.log('All auth data cleared');
}
/**
* 获取Token头部信息用于HTTP请求
* @returns {object|null} Authorization头部或null
*/
static getAuthHeader() {
const token = this.getToken();
return token ? { 'Authorization': `Bearer ${token}` } : null;
}
/**
* 检查用户是否已登录
* @returns {boolean} 是否已登录
*/
static isLoggedIn() {
return this.isTokenValid() && this.getUser() !== null;
}
/**
* 获取Token剩余有效时间
* @returns {number} 剩余秒数,-1表示已过期或无效
*/
static getTokenRemainingTime() {
const token = this.getToken();
if (!token) return -1;
const payload = this.parseToken(token);
if (!payload || !payload.exp) return -1;
const currentTime = Math.floor(Date.now() / 1000);
const remainingTime = payload.exp - currentTime;
return remainingTime > 0 ? remainingTime : -1;
}
}
// 导出供其他模块使用
if (typeof module !== 'undefined' && module.exports) {
module.exports = TokenManager;
}