A组认证加固: P0兜底+Token刷新+环境检测+OTP+RBRAC落地+P1日志审计+Token撤销 - 全局一致性审查通过
This commit is contained in:
@@ -41,6 +41,24 @@ const routes = [
|
||||
title: '正在加载...',
|
||||
},
|
||||
},
|
||||
{
|
||||
// 错误提示页面(OAuth2 回调异常兜底)
|
||||
path: '/error',
|
||||
name: 'ErrorPage',
|
||||
component: () => import('@/views/ErrorPage.vue'),
|
||||
meta: {
|
||||
title: '登录失败',
|
||||
},
|
||||
},
|
||||
{
|
||||
// 错误提示页面(/login/error 别名,兼容后端重定向)
|
||||
path: '/login/error',
|
||||
name: 'LoginError',
|
||||
component: () => import('@/views/ErrorPage.vue'),
|
||||
meta: {
|
||||
title: '登录失败',
|
||||
},
|
||||
},
|
||||
{
|
||||
// 404 页面
|
||||
path: '/:pathMatch(.*)*',
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<!-- OAuth2 登录失败错误页面 -->
|
||||
<div class="portal-error">
|
||||
<div class="error-content">
|
||||
<!-- 错误图标 -->
|
||||
<div class="error-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75.75 0 000 1.5z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- 登录失败标题 -->
|
||||
<h2 class="error-title">登录失败</h2>
|
||||
|
||||
<!-- 错误信息 -->
|
||||
<p class="error-message">{{ errorMessage }}</p>
|
||||
|
||||
<!-- 重新登录按钮 -->
|
||||
<button class="back-button" @click="retryLogin">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20">
|
||||
<path fill-rule="evenodd" d="M4.5 9.75a6 6 0 0111.573-2.226 3.75 3.75 0 014.133 4.303A4.5 4.5 0 0118 20.25H6.75a5.25 5.25 0 01-2.23-10.004 6.072 6.072 0 01-.02-.496z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
重新登录
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
// 从路由 query 获取错误码和错误信息
|
||||
const errorCode = computed(() => {
|
||||
const code = route.query.code as string
|
||||
return code || 'Error'
|
||||
})
|
||||
|
||||
// 错误信息:优先使用 message 参数,否则根据错误码生成友好提示
|
||||
const errorMessage = computed(() => {
|
||||
const message = route.query.message as string
|
||||
if (message) {
|
||||
return message
|
||||
}
|
||||
// 根据错误码生成友好提示
|
||||
const code = errorCode.value
|
||||
const errorMessages: Record<string, string> = {
|
||||
'oauth_failed': '登录过程出现异常,请重试',
|
||||
'missing_params': '授权参数不完整,请重试',
|
||||
'state_expired': '授权已过期,请重新进入',
|
||||
'api_failed': '企业微信服务异常,请重试',
|
||||
'empty_userid': '无法获取您的企业微信身份,请重试',
|
||||
'wecom_48001': '应用权限不足,请联系管理员',
|
||||
'wecom_50001': '授权已失效,请重新进入',
|
||||
}
|
||||
return errorMessages[code] || '认证过程中出现错误,请重试'
|
||||
})
|
||||
|
||||
// 重新登录:跳转回首页重新发起 OAuth2 流程
|
||||
const retryLogin = () => {
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 如果没有错误信息,重定向回入口
|
||||
if (!route.query.code && !route.query.message) {
|
||||
router.replace('/')
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 页面容器 */
|
||||
.portal-error {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
|
||||
}
|
||||
|
||||
/* 错误内容 */
|
||||
.error-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
padding: 48px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 错误图标 - 企微绿色 */
|
||||
.error-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
color: #10b981;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.error-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 登录失败标题 */
|
||||
.error-title {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #f1f5f9;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 错误信息 */
|
||||
.error-message {
|
||||
font-size: 16px;
|
||||
color: #94a3b8;
|
||||
margin: 0;
|
||||
max-width: 360px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 重新登录按钮 - 企微绿色主题 */
|
||||
.back-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 24px;
|
||||
margin-top: 16px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
background-color: #10b981;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.back-button:hover {
|
||||
background-color: #059669;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
|
||||
}
|
||||
|
||||
.back-button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.back-button svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user