feat(安全): 增加验证码和安全验证功能

refactor(XSS): 重构XSS过滤逻辑并添加JSON反序列化过滤

feat(防重放): 前端添加防重放攻击机制

fix(验证码): 优化验证码生成和异常处理

style: 格式化代码并修复部分警告
This commit is contained in:
ikmkj
2026-03-03 18:45:08 +08:00
parent 61aeba9c65
commit 07454a28d2
11 changed files with 485 additions and 102 deletions

View File

@@ -2,6 +2,7 @@ import axios from 'axios'
import { useUserStore } from '../stores/user'
import { ElMessage } from 'element-plus'
import router from '../router'
import { getReplayAttackHeaders, needsReplayAttackValidation } from './security'
const instance = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
@@ -20,6 +21,13 @@ instance.interceptors.request.use(
if (userStore.token) {
config.headers['Authorization'] = `Bearer ${userStore.token}`
}
// 添加防重放攻击请求头POST/PUT/DELETE 请求)
if (needsReplayAttackValidation(config.method, config.url)) {
const replayHeaders = getReplayAttackHeaders()
config.headers['X-Timestamp'] = replayHeaders['X-Timestamp']
config.headers['X-Nonce'] = replayHeaders['X-Nonce']
}
} catch (error) {
console.warn('Failed to get user store:', error)
}
@@ -46,15 +54,47 @@ instance.interceptors.response.use(
}
},
error => {
if (error.response && error.response.status === 401) {
try {
const userStore = useUserStore()
userStore.logout();
ElMessage.error('登录已过期,请重新登录');
router.push('/login');
} catch (error) {
console.warn('Failed to get user store:', error)
if (error.response) {
const status = error.response.status;
const data = error.response.data;
// 401 - 未授权
if (status === 401) {
try {
const userStore = useUserStore()
userStore.logout();
ElMessage.error('登录已过期,请重新登录');
router.push('/login');
} catch (error) {
console.warn('Failed to get user store:', error)
}
return Promise.reject(error);
}
// 429 - 请求过于频繁
if (status === 429) {
const msg = data?.msg || '请求过于频繁,请稍后再试';
ElMessage.error(msg);
return Promise.reject(new Error(msg));
}
// 400 - 验证码错误等
if (status === 400) {
const msg = data?.msg || '请求参数错误';
ElMessage.error(msg);
return Promise.reject(new Error(msg));
}
// 503 - 服务器繁忙(内存不足)
if (status === 503) {
const msg = data?.msg || '服务器繁忙,请稍后再试';
ElMessage.error(msg);
return Promise.reject(new Error(msg));
}
// 其他错误,显示后端返回的消息
const msg = data?.msg || error.message;
ElMessage.error(msg);
} else {
ElMessage({
message: error.message,