1. 管理端 request.js: 所有401均优先显示后端实际message, 非登录页才清除Token并跳转 2. 前台用户端 request.js: 区分登录/注册请求与已认证请求, 登录失败时只显示后端message,不清Token不跳转 3. 后端 auth_service: 登录时用户不存在统一返回"账号或密码错误" (防止用户枚举攻击,不再返回404"用户不存在") Made-with: Cursor
74 lines
2.0 KiB
JavaScript
74 lines
2.0 KiB
JavaScript
/**
|
||
* HTTP 请求封装(管理后台)
|
||
*
|
||
* 基于 Axios 封装,提供:
|
||
* - 基础 URL 配置(开发环境通过 Vite proxy 代理)
|
||
* - 请求拦截:自动附加 Authorization Header
|
||
* - 响应拦截:统一处理错误码(401 跳转登录等)
|
||
*
|
||
* 对应后端 API 规范见 docs/api/README.md
|
||
*/
|
||
import axios from 'axios'
|
||
import { ElMessage } from 'element-plus'
|
||
import router from '@/router'
|
||
|
||
/** Axios 实例 */
|
||
const service = axios.create({
|
||
baseURL: import.meta.env.VITE_API_BASE_URL || '',
|
||
timeout: 15000,
|
||
headers: { 'Content-Type': 'application/json' }
|
||
})
|
||
|
||
/**
|
||
* 请求拦截器
|
||
* 自动从 localStorage 读取 Token 并附加到 Authorization Header
|
||
*/
|
||
service.interceptors.request.use(
|
||
(config) => {
|
||
const token = localStorage.getItem('admin_token')
|
||
if (token) {
|
||
config.headers.Authorization = `Bearer ${token}`
|
||
}
|
||
return config
|
||
},
|
||
(error) => Promise.reject(error)
|
||
)
|
||
|
||
/**
|
||
* 响应拦截器
|
||
* 统一处理后端 { code, message, data } 响应格式
|
||
*/
|
||
service.interceptors.response.use(
|
||
(response) => {
|
||
const { data } = response
|
||
if (data.code === 0) {
|
||
return data
|
||
}
|
||
ElMessage.error(data.message || '请求失败')
|
||
return Promise.reject(data)
|
||
},
|
||
(error) => {
|
||
if (error.response) {
|
||
const { status, data } = error.response
|
||
if (status === 401) {
|
||
const isOnLoginPage = router.currentRoute.value.path === '/login'
|
||
ElMessage.error(data?.message || '登录已过期,请重新登录')
|
||
if (!isOnLoginPage) {
|
||
localStorage.removeItem('admin_token')
|
||
localStorage.removeItem('admin_user')
|
||
router.push('/login')
|
||
}
|
||
} else if (status === 403) {
|
||
ElMessage.error(data?.message || '没有访问权限')
|
||
} else {
|
||
ElMessage.error(data?.message || `请求错误 (${status})`)
|
||
}
|
||
} else {
|
||
ElMessage.error('网络异常,请检查网络连接')
|
||
}
|
||
return Promise.reject(error)
|
||
}
|
||
)
|
||
|
||
export default service
|