security: 实施 HttpOnly Cookie 鉴权方案

## 后端修改
- 新增 /api/logout 接口清除认证 Cookie

## 前端修改
- 移除 localStorage 存储 token/refreshToken(防止 XSS 窃取)
- 移除所有手动 Authorization 头(共36处)
- checkLoginStatus 改为直接调用 API 验证(Cookie 自动携带)
- logout 改为调用后端接口清除 Cookie
- 简化 token 刷新逻辑

## 安全性提升
- Token 从 localStorage 迁移到 HttpOnly Cookie
- XSS 攻击无法通过 JS 读取 token
- 配合 SameSite 属性防御 CSRF 攻击

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-30 10:33:27 +08:00
parent d1c5b0c1bf
commit d05e3a22f1
2 changed files with 82 additions and 153 deletions

View File

@@ -1731,6 +1731,13 @@ app.post('/api/refresh-token', (req, res) => {
}); });
}); });
// 登出清除Cookie
app.post('/api/logout', (req, res) => {
// 清除认证Cookie
res.clearCookie('token', { path: '/' });
res.json({ success: true, message: '已登出' });
});
// ===== 需要认证的API ===== // ===== 需要认证的API =====
// 获取当前用户信息 // 获取当前用户信息

View File

@@ -322,9 +322,7 @@ createApp({
// 加载用户主题设置(登录后调用) // 加载用户主题设置(登录后调用)
async loadUserTheme() { async loadUserTheme() {
try { try {
const res = await axios.get(`${this.apiBase}/api/user/theme`, { const res = await axios.get(`${this.apiBase}/api/user/theme`);
headers: { Authorization: `Bearer ${this.token}` }
});
if (res.data.success) { if (res.data.success) {
this.globalTheme = res.data.theme.global; this.globalTheme = res.data.theme.global;
this.userThemePreference = res.data.theme.user; this.userThemePreference = res.data.theme.user;
@@ -352,7 +350,6 @@ createApp({
try { try {
const res = await axios.post(`${this.apiBase}/api/user/theme`, const res = await axios.post(`${this.apiBase}/api/user/theme`,
{ theme }, { theme },
{ headers: { Authorization: `Bearer ${this.token}` }}
); );
if (res.data.success) { if (res.data.success) {
this.userThemePreference = res.data.theme.user; this.userThemePreference = res.data.theme.user;
@@ -378,7 +375,6 @@ createApp({
console.log('[主题] 设置全局主题:', theme); console.log('[主题] 设置全局主题:', theme);
const res = await axios.post(`${this.apiBase}/api/admin/settings`, const res = await axios.post(`${this.apiBase}/api/admin/settings`,
{ global_theme: theme }, { global_theme: theme },
{ headers: { Authorization: `Bearer ${this.token}` }}
); );
console.log('[主题] API响应:', res.data); console.log('[主题] API响应:', res.data);
if (res.data.success) { if (res.data.success) {
@@ -542,9 +538,8 @@ handleDragLeave(e) {
this.showCaptcha = false; this.showCaptcha = false;
this.loginForm.captcha = ''; this.loginForm.captcha = '';
// 保存token到localStorage // 保存用户信息到localStorage(非敏感信息,用于页面刷新后恢复)
localStorage.setItem('token', this.token); // 注意token 通过 HttpOnly Cookie 传递,不再存储在 localStorage
localStorage.setItem('refreshToken', this.refreshToken);
localStorage.setItem('user', JSON.stringify(this.user)); localStorage.setItem('user', JSON.stringify(this.user));
// 启动token自动刷新在过期前5分钟刷新 // 启动token自动刷新在过期前5分钟刷新
@@ -565,11 +560,8 @@ handleDragLeave(e) {
console.log('[登录] SFTP未配置但用户有本地存储权限自动切换到本地存储'); console.log('[登录] SFTP未配置但用户有本地存储权限自动切换到本地存储');
this.storageType = 'local'; this.storageType = 'local';
// 异步更新到后端(不等待,避免阻塞登录流程) // 异步更新到后端(不等待,避免阻塞登录流程)
axios.post( axios.post(`${this.apiBase}/api/user/switch-storage`, { storage_type: 'local' })
`${this.apiBase}/api/user/switch-storage`, .catch(err => console.error('[登录] 自动切换存储类型失败:', err));
{ storage_type: 'local' },
{ headers: { Authorization: `Bearer ${this.token}` } }
).catch(err => console.error('[登录] 自动切换存储类型失败:', err));
} }
} }
@@ -755,7 +747,6 @@ handleDragLeave(e) {
const response = await axios.post( const response = await axios.post(
`${this.apiBase}/api/user/update-ftp`, `${this.apiBase}/api/user/update-ftp`,
this.ftpConfigForm, this.ftpConfigForm,
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -769,8 +760,7 @@ handleDragLeave(e) {
const switchResponse = await axios.post( const switchResponse = await axios.post(
`${this.apiBase}/api/user/switch-storage`, `${this.apiBase}/api/user/switch-storage`,
{ storage_type: 'sftp' }, { storage_type: 'sftp' },
{ headers: { Authorization: `Bearer ${this.token}` } } );
);
if (switchResponse.data.success) { if (switchResponse.data.success) {
this.storageType = 'sftp'; this.storageType = 'sftp';
@@ -800,18 +790,12 @@ handleDragLeave(e) {
{ {
username: this.adminProfileForm.username username: this.adminProfileForm.username
}, },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
alert('用户名已更新!请重新登录。'); alert('用户名已更新!请重新登录。');
// 更新token和用户信息 // 更新用户信息(后端已通过 Cookie 更新 token
if (response.data.token) {
this.token = response.data.token;
localStorage.setItem('token', response.data.token);
}
if (response.data.user) { if (response.data.user) {
this.user = response.data.user; this.user = response.data.user;
localStorage.setItem('user', JSON.stringify(response.data.user)); localStorage.setItem('user', JSON.stringify(response.data.user));
@@ -843,7 +827,6 @@ handleDragLeave(e) {
current_password: this.changePasswordForm.current_password, current_password: this.changePasswordForm.current_password,
new_password: this.changePasswordForm.new_password new_password: this.changePasswordForm.new_password
}, },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -860,7 +843,6 @@ handleDragLeave(e) {
try { try {
const response = await axios.get( const response = await axios.get(
`${this.apiBase}/api/user/profile`, `${this.apiBase}/api/user/profile`,
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success && response.data.user) { if (response.data.success && response.data.user) {
@@ -975,7 +957,6 @@ handleDragLeave(e) {
const response = await axios.post( const response = await axios.post(
`${this.apiBase}/api/user/update-username`, `${this.apiBase}/api/user/update-username`,
{ username: this.usernameForm.newUsername }, { username: this.usernameForm.newUsername },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -995,7 +976,6 @@ handleDragLeave(e) {
const response = await axios.post( const response = await axios.post(
`${this.apiBase}/api/user/update-profile`, `${this.apiBase}/api/user/update-profile`,
{ email: this.profileForm.email }, { email: this.profileForm.email },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -1011,14 +991,19 @@ handleDragLeave(e) {
} }
}, },
logout() { async logout() {
// 调用后端清除 HttpOnly Cookie
try {
await axios.post(`${this.apiBase}/api/logout`);
} catch (err) {
console.error('[登出] 清除Cookie失败:', err);
}
this.isLoggedIn = false; this.isLoggedIn = false;
this.user = null; this.user = null;
this.token = null; this.token = null;
this.refreshToken = null; this.refreshToken = null;
this.stopTokenRefresh(); this.stopTokenRefresh();
localStorage.removeItem('token');
localStorage.removeItem('refreshToken');
localStorage.removeItem('user'); localStorage.removeItem('user');
localStorage.removeItem('lastView'); localStorage.removeItem('lastView');
this.showResendVerify = false; this.showResendVerify = false;
@@ -1041,82 +1026,61 @@ handleDragLeave(e) {
} }
}, },
// 检查本地存储的登录状态 // 检查登录状态(通过 HttpOnly Cookie 验证)
async checkLoginStatus() { async checkLoginStatus() {
const token = localStorage.getItem('token'); // 直接调用API验证Cookie会自动携带
const refreshToken = localStorage.getItem('refreshToken'); try {
const user = localStorage.getItem('user'); const response = await axios.get(`${this.apiBase}/api/user/profile`);
if (token && user) { if (response.data.success && response.data.user) {
this.token = token; // Cookie有效用户已登录
this.refreshToken = refreshToken; this.user = response.data.user;
this.user = JSON.parse(user); this.isLoggedIn = true;
// 先验证token是否有效 // 更新localStorage中的用户信息非敏感信息
try { localStorage.setItem('user', JSON.stringify(this.user));
const response = await axios.get(
`${this.apiBase}/api/user/profile`,
{ headers: { Authorization: `Bearer ${token}` } }
);
if (response.data.success && response.data.user) { // 从最新的用户信息初始化存储相关字段
// token有效更新用户信息 this.storagePermission = this.user.storage_permission || 'sftp_only';
this.user = response.data.user; this.storageType = this.user.current_storage_type || 'sftp';
this.isLoggedIn = true; this.localQuota = this.user.local_storage_quota || 0;
this.localUsed = this.user.local_storage_used || 0;
// 更新localStorage中的用户信息 console.log('[页面加载] Cookie验证成功存储权限:', this.storagePermission, '存储类型:', this.storageType);
localStorage.setItem('user', JSON.stringify(this.user));
// 从最新的用户信息初始化存储相关字段 // 启动token自动刷新假设剩余1.5小时,实际由服务端控制)
this.storagePermission = this.user.storage_permission || 'sftp_only'; this.startTokenRefresh(1.5 * 60 * 60 * 1000);
this.storageType = this.user.current_storage_type || 'sftp';
this.localQuota = this.user.local_storage_quota || 0;
this.localUsed = this.user.local_storage_used || 0;
console.log('[页面加载] Token验证成功存储权限:', this.storagePermission, '存储类型:', this.storageType); // 启动定期检查用户配置
this.startProfileSync();
// 加载用户主题设置
this.loadUserTheme();
// 启动token自动刷新假设剩余1.5小时,实际由服务端控制 // 读取上次停留的视图(需合法才生效
this.startTokenRefresh(1.5 * 60 * 60 * 1000); const savedView = localStorage.getItem('lastView');
let targetView = null;
// 启动定期检查用户配置 if (savedView && this.isViewAllowed(savedView)) {
this.startProfileSync(); targetView = savedView;
// 加载用户主题设置 } else if (this.user.is_admin) {
this.loadUserTheme(); targetView = 'admin';
} else if (this.storagePermission === 'sftp_only' && !this.user.has_ftp_config) {
// 读取上次停留的视图(需合法才生效) targetView = 'settings';
const savedView = localStorage.getItem('lastView');
let targetView = null;
if (savedView && this.isViewAllowed(savedView)) {
targetView = savedView;
} else if (this.user.is_admin) {
targetView = 'admin';
} else if (this.storagePermission === 'sftp_only' && !this.user.has_ftp_config) {
targetView = 'settings';
} else {
targetView = 'files';
}
// 强制切换到目标视图并加载数据
this.switchView(targetView, true);
} else { } else {
// 响应异常尝试刷新token targetView = 'files';
await this.tryRefreshOrLogout();
} }
} catch (error) {
console.warn('[页面加载] Token验证失败:', error.response?.status || error.message); // 强制切换到目标视图并加载数据
// token无效或过期尝试使用refresh token刷新 this.switchView(targetView, true);
if (error.response?.status === 401 && this.refreshToken) {
console.log('[页面加载] 尝试使用refresh token刷新...');
const refreshed = await this.doRefreshToken();
if (refreshed) {
// 刷新成功,重新检查登录状态
await this.checkLoginStatus();
return;
}
}
// 刷新失败或无refresh token清除登录状态
this.handleTokenExpired();
} }
} catch (error) {
// 401表示未登录或Cookie过期静默处理用户需要重新登录
if (error.response?.status === 401) {
console.log('[页面加载] 未登录或Cookie已过期');
} else {
console.warn('[页面加载] 验证登录状态失败:', error.message);
}
// 清理可能残留的用户信息
localStorage.removeItem('user');
} }
}, },
@@ -1134,14 +1098,12 @@ handleDragLeave(e) {
// 处理token过期/失效 // 处理token过期/失效
handleTokenExpired() { handleTokenExpired() {
console.log('[认证] Token已失效,清除登录状态'); console.log('[认证] Cookie已失效,清除登录状态');
this.isLoggedIn = false; this.isLoggedIn = false;
this.user = null; this.user = null;
this.token = null; this.token = null;
this.refreshToken = null; this.refreshToken = null;
this.stopTokenRefresh(); this.stopTokenRefresh();
localStorage.removeItem('token');
localStorage.removeItem('refreshToken');
localStorage.removeItem('user'); localStorage.removeItem('user');
localStorage.removeItem('lastView'); localStorage.removeItem('lastView');
this.stopProfileSync(); this.stopProfileSync();
@@ -1168,7 +1130,7 @@ handleDragLeave(e) {
} }
}, },
// 执行token刷新 // 执行token刷新(通过 refreshToken 刷新 HttpOnly Cookie 中的 access token
async doRefreshToken() { async doRefreshToken() {
if (!this.refreshToken) { if (!this.refreshToken) {
console.log('[认证] 无refresh token无法刷新'); console.log('[认证] 无refresh token无法刷新');
@@ -1182,9 +1144,8 @@ handleDragLeave(e) {
}); });
if (response.data.success) { if (response.data.success) {
this.token = response.data.token; // 后端已自动更新 HttpOnly Cookie 中的 token
localStorage.setItem('token', this.token); console.log('[认证] Token刷新成功Cookie已更新');
console.log('[认证] Token刷新成功');
// 继续下一次刷新 // 继续下一次刷新
const expiresIn = response.data.expiresIn || (2 * 60 * 60 * 1000); const expiresIn = response.data.expiresIn || (2 * 60 * 60 * 1000);
@@ -1220,8 +1181,7 @@ handleDragLeave(e) {
try { try {
const response = await axios.get(`${this.apiBase}/api/files`, { const response = await axios.get(`${this.apiBase}/api/files`, {
params: { path }, params: { path }
headers: { Authorization: `Bearer ${this.token}` }
}); });
if (response.data.success) { if (response.data.success) {
@@ -1325,7 +1285,6 @@ handleDragLeave(e) {
const response = await axios.post( const response = await axios.post(
`${this.apiBase}/api/files/rename`, `${this.apiBase}/api/files/rename`,
this.renameForm, this.renameForm,
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -1358,8 +1317,6 @@ handleDragLeave(e) {
const response = await axios.post(`${this.apiBase}/api/files/mkdir`, { const response = await axios.post(`${this.apiBase}/api/files/mkdir`, {
path: this.currentPath, path: this.currentPath,
folderName: folderName folderName: folderName
}, {
headers: { 'Authorization': `Bearer ${this.token}` }
}); });
if (response.data.success) { if (response.data.success) {
@@ -1388,8 +1345,6 @@ handleDragLeave(e) {
const response = await axios.post(`${this.apiBase}/api/files/folder-info`, { const response = await axios.post(`${this.apiBase}/api/files/folder-info`, {
path: this.currentPath, path: this.currentPath,
folderName: file.name folderName: file.name
}, {
headers: { 'Authorization': `Bearer ${this.token}` }
}); });
if (response.data.success) { if (response.data.success) {
@@ -1614,7 +1569,6 @@ handleDragLeave(e) {
path: this.currentPath, path: this.currentPath,
isDirectory: file.isDirectory isDirectory: file.isDirectory
}, },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -1680,7 +1634,6 @@ handleDragLeave(e) {
password: this.shareAllForm.password || null, password: this.shareAllForm.password || null,
expiry_days: expiryDays expiry_days: expiryDays
}, },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -1712,7 +1665,6 @@ handleDragLeave(e) {
password: this.shareFileForm.password || null, password: this.shareFileForm.password || null,
expiry_days: expiryDays expiry_days: expiryDays
}, },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -1798,7 +1750,6 @@ handleDragLeave(e) {
const response = await axios.post(`${this.apiBase}/api/upload`, formData, { const response = await axios.post(`${this.apiBase}/api/upload`, formData, {
headers: { headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
}, },
timeout: 30 * 60 * 1000, // 30分钟超时支持大文件上传 timeout: 30 * 60 * 1000, // 30分钟超时支持大文件上传
@@ -1864,9 +1815,7 @@ handleDragLeave(e) {
async loadShares() { async loadShares() {
try { try {
const response = await axios.get(`${this.apiBase}/api/share/my`, { const response = await axios.get(`${this.apiBase}/api/share/my`);
headers: { Authorization: `Bearer ${this.token}` }
});
if (response.data.success) { if (response.data.success) {
this.shares = response.data.shares; this.shares = response.data.shares;
@@ -1881,9 +1830,7 @@ handleDragLeave(e) {
this.shareForm.path = this.currentPath; this.shareForm.path = this.currentPath;
try { try {
const response = await axios.post(`${this.apiBase}/api/share/create`, this.shareForm, { const response = await axios.post(`${this.apiBase}/api/share/create`, this.shareForm);
headers: { Authorization: `Bearer ${this.token}` }
});
if (response.data.success) { if (response.data.success) {
this.shareResult = response.data; this.shareResult = response.data;
@@ -1899,9 +1846,7 @@ handleDragLeave(e) {
if (!confirm('确定要删除这个分享吗?')) return; if (!confirm('确定要删除这个分享吗?')) return;
try { try {
const response = await axios.delete(`${this.apiBase}/api/share/${id}`, { const response = await axios.delete(`${this.apiBase}/api/share/${id}`);
headers: { Authorization: `Bearer ${this.token}` }
});
if (response.data.success) { if (response.data.success) {
alert('分享已删除'); alert('分享已删除');
@@ -2000,9 +1945,7 @@ handleDragLeave(e) {
async loadUsers() { async loadUsers() {
try { try {
const response = await axios.get(`${this.apiBase}/api/admin/users`, { const response = await axios.get(`${this.apiBase}/api/admin/users`);
headers: { Authorization: `Bearer ${this.token}` }
});
if (response.data.success) { if (response.data.success) {
this.adminUsers = response.data.users; this.adminUsers = response.data.users;
@@ -2021,7 +1964,6 @@ handleDragLeave(e) {
const response = await axios.post( const response = await axios.post(
`${this.apiBase}/api/admin/users/${userId}/ban`, `${this.apiBase}/api/admin/users/${userId}/ban`,
{ banned }, { banned },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -2038,9 +1980,7 @@ handleDragLeave(e) {
if (!confirm('确定要删除这个用户吗?此操作不可恢复!')) return; if (!confirm('确定要删除这个用户吗?此操作不可恢复!')) return;
try { try {
const response = await axios.delete(`${this.apiBase}/api/admin/users/${userId}`, { const response = await axios.delete(`${this.apiBase}/api/admin/users/${userId}`);
headers: { Authorization: `Bearer ${this.token}` }
});
if (response.data.success) { if (response.data.success) {
alert('用户已删除'); alert('用户已删除');
@@ -2123,8 +2063,7 @@ handleDragLeave(e) {
const response = await axios.get( const response = await axios.get(
`${this.apiBase}/api/admin/users/${this.inspectionUser.id}/files`, `${this.apiBase}/api/admin/users/${this.inspectionUser.id}/files`,
{ {
params: { path }, params: { path }
headers: { Authorization: `Bearer ${this.token}` }
} }
); );
@@ -2166,7 +2105,6 @@ handleDragLeave(e) {
try { try {
const response = await axios.get( const response = await axios.get(
`${this.apiBase}/api/user/profile`, `${this.apiBase}/api/user/profile`,
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success && response.data.user) { if (response.data.success && response.data.user) {
@@ -2228,7 +2166,6 @@ handleDragLeave(e) {
try { try {
const response = await axios.get( const response = await axios.get(
`${this.apiBase}/api/user/sftp-usage`, `${this.apiBase}/api/user/sftp-usage`,
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -2287,7 +2224,6 @@ handleDragLeave(e) {
const response = await axios.post( const response = await axios.post(
`${this.apiBase}/api/user/switch-storage`, `${this.apiBase}/api/user/switch-storage`,
{ storage_type: type }, { storage_type: type },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -2426,7 +2362,6 @@ handleDragLeave(e) {
storage_permission: this.editStorageForm.storage_permission, storage_permission: this.editStorageForm.storage_permission,
local_storage_quota: quotaBytes local_storage_quota: quotaBytes
}, },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -2506,9 +2441,7 @@ handleDragLeave(e) {
async loadSystemSettings() { async loadSystemSettings() {
try { try {
const response = await axios.get(`${this.apiBase}/api/admin/settings`, { const response = await axios.get(`${this.apiBase}/api/admin/settings`);
headers: { Authorization: `Bearer ${this.token}` }
});
if (response.data.success) { if (response.data.success) {
const settings = response.data.settings; const settings = response.data.settings;
@@ -2537,9 +2470,7 @@ handleDragLeave(e) {
async loadServerStorageStats() { async loadServerStorageStats() {
try { try {
const response = await axios.get(`${this.apiBase}/api/admin/storage-stats`, { const response = await axios.get(`${this.apiBase}/api/admin/storage-stats`);
headers: { Authorization: `Bearer ${this.token}` }
});
if (response.data.success) { if (response.data.success) {
this.serverStorageStats = response.data.stats; this.serverStorageStats = response.data.stats;
@@ -2570,8 +2501,7 @@ handleDragLeave(e) {
const response = await axios.post( const response = await axios.post(
`${this.apiBase}/api/admin/settings`, `${this.apiBase}/api/admin/settings`,
payload, payload
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -2590,7 +2520,6 @@ handleDragLeave(e) {
const response = await axios.post( const response = await axios.post(
`${this.apiBase}/api/admin/settings/test-smtp`, `${this.apiBase}/api/admin/settings/test-smtp`,
{ to: this.systemSettings.smtp.user }, { to: this.systemSettings.smtp.user },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
this.showToast('success', '成功', response.data.message || '测试邮件已发送'); this.showToast('success', '成功', response.data.message || '测试邮件已发送');
} catch (error) { } catch (error) {
@@ -2604,9 +2533,7 @@ handleDragLeave(e) {
async loadHealthCheck() { async loadHealthCheck() {
this.healthCheck.loading = true; this.healthCheck.loading = true;
try { try {
const response = await axios.get(`${this.apiBase}/api/admin/health-check`, { const response = await axios.get(`${this.apiBase}/api/admin/health-check`);
headers: { Authorization: `Bearer ${this.token}` }
});
if (response.data.success) { if (response.data.success) {
this.healthCheck.overallStatus = response.data.overallStatus; this.healthCheck.overallStatus = response.data.overallStatus;
@@ -2680,9 +2607,7 @@ handleDragLeave(e) {
params.append('keyword', this.systemLogs.filters.keyword); params.append('keyword', this.systemLogs.filters.keyword);
} }
const response = await axios.get(`${this.apiBase}/api/admin/logs?${params}`, { const response = await axios.get(`${this.apiBase}/api/admin/logs?${params}`);
headers: { Authorization: `Bearer ${this.token}` }
});
if (response.data.success) { if (response.data.success) {
this.systemLogs.logs = response.data.logs; this.systemLogs.logs = response.data.logs;
@@ -2766,7 +2691,6 @@ handleDragLeave(e) {
const response = await axios.post( const response = await axios.post(
`${this.apiBase}/api/admin/logs/cleanup`, `${this.apiBase}/api/admin/logs/cleanup`,
{ keepDays: 90 }, { keepDays: 90 },
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -2787,7 +2711,6 @@ handleDragLeave(e) {
try { try {
const response = await axios.get( const response = await axios.get(
`${this.apiBase}/api/admin/check-upload-tool`, `${this.apiBase}/api/admin/check-upload-tool`,
{ headers: { Authorization: `Bearer ${this.token}` } }
); );
if (response.data.success) { if (response.data.success) {
@@ -2844,7 +2767,6 @@ handleDragLeave(e) {
formData, formData,
{ {
headers: { headers: {
Authorization: `Bearer ${this.token}`,
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
} }
} }