fix: 统一前后端错误提示处理,修复3个问题

1. 管理端 request.js: 所有401均优先显示后端实际message,
   非登录页才清除Token并跳转
2. 前台用户端 request.js: 区分登录/注册请求与已认证请求,
   登录失败时只显示后端message,不清Token不跳转
3. 后端 auth_service: 登录时用户不存在统一返回"账号或密码错误"
   (防止用户枚举攻击,不再返回404"用户不存在")

Made-with: Cursor
This commit is contained in:
bujinyuan
2026-03-02 14:05:03 +08:00
parent 8a818f8035
commit e1348f57f2
3 changed files with 14 additions and 18 deletions

View File

@@ -52,10 +52,8 @@ service.interceptors.response.use(
const { status, data } = error.response const { status, data } = error.response
if (status === 401) { if (status === 401) {
const isOnLoginPage = router.currentRoute.value.path === '/login' const isOnLoginPage = router.currentRoute.value.path === '/login'
if (isOnLoginPage) { ElMessage.error(data?.message || '登录已过期,请重新登录')
ElMessage.error(data?.message || '账号或密码错误') if (!isOnLoginPage) {
} else {
ElMessage.error('登录已过期,请重新登录')
localStorage.removeItem('admin_token') localStorage.removeItem('admin_token')
localStorage.removeItem('admin_user') localStorage.removeItem('admin_user')
router.push('/login') router.push('/login')

View File

@@ -139,11 +139,11 @@ func (s *AuthService) Login(ctx context.Context, req *dto.LoginRequest, clientIP
} }
}() }()
// 按用户名或邮箱查找用户 // 按用户名或邮箱查找用户(用户不存在时统一返回密码错误,防止枚举攻击)
user, findErr := s.userDAO.FindByAccount(ctx, req.Account) user, findErr := s.userDAO.FindByAccount(ctx, req.Account)
if findErr != nil { if findErr != nil {
if errors.Is(findErr, gorm.ErrRecordNotFound) { if errors.Is(findErr, gorm.ErrRecordNotFound) {
err = ErrUserNotFound err = ErrPasswordWrong
} else { } else {
err = findErr err = findErr
} }

View File

@@ -73,18 +73,16 @@ const request = (options) => {
reject(data) reject(data)
} }
} else if (statusCode === 401) { } else if (statusCode === 401) {
// Token 过期或无效,清除本地 Token 并跳转登录页 const isAuthEndpoint = /\/auth\/(login|register)$/.test(options.url)
removeToken() const message = data?.message || '登录已过期,请重新登录'
uni.showToast({ uni.showToast({ title: message, icon: 'none', duration: 2000 })
title: '登录已过期,请重新登录', if (!isAuthEndpoint) {
icon: 'none', removeToken()
duration: 2000 setTimeout(() => {
}) uni.reLaunch({ url: '/pages/auth/login' })
// 延迟跳转,让 Toast 有时间显示 }, 1500)
setTimeout(() => { }
uni.reLaunch({ url: '/pages/auth/login' }) reject({ code: 401, message })
}, 1500)
reject({ code: 401, message: '认证已失效' })
} else if (statusCode === 403) { } else if (statusCode === 403) {
uni.showToast({ uni.showToast({
title: data.message || '没有访问权限', title: data.message || '没有访问权限',