mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 00:53:33 +00:00
feat: 实现完整用户管理系统和LDAP认证集成
- 新增LDAP认证服务支持用户登录验证 - 实现用户服务包含会话管理和权限控制 - 添加用户专用路由和API端点 - 扩展认证中间件支持用户和管理员双重身份 - 新增用户仪表板、API密钥管理和使用统计界面 - 完善前端用户管理组件和路由配置 - 支持用户自助API密钥创建和管理 - 添加管理员用户管理功能包含角色权限控制 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { APP_CONFIG } from '@/config/app'
|
||||
|
||||
// 路由懒加载
|
||||
const LoginView = () => import('@/views/LoginView.vue')
|
||||
const UserLoginView = () => import('@/views/UserLoginView.vue')
|
||||
const UserDashboardView = () => import('@/views/UserDashboardView.vue')
|
||||
const UserManagementView = () => import('@/views/UserManagementView.vue')
|
||||
const MainLayout = () => import('@/components/layout/MainLayout.vue')
|
||||
const DashboardView = () => import('@/views/DashboardView.vue')
|
||||
const ApiKeysView = () => import('@/views/ApiKeysView.vue')
|
||||
@@ -35,6 +39,22 @@ const routes = [
|
||||
component: LoginView,
|
||||
meta: { requiresAuth: false }
|
||||
},
|
||||
{
|
||||
path: '/admin-login',
|
||||
redirect: '/login'
|
||||
},
|
||||
{
|
||||
path: '/user-login',
|
||||
name: 'UserLogin',
|
||||
component: UserLoginView,
|
||||
meta: { requiresAuth: false, userAuth: true }
|
||||
},
|
||||
{
|
||||
path: '/user-dashboard',
|
||||
name: 'UserDashboard',
|
||||
component: UserDashboardView,
|
||||
meta: { requiresUserAuth: true }
|
||||
},
|
||||
{
|
||||
path: '/api-stats',
|
||||
name: 'ApiStats',
|
||||
@@ -101,6 +121,18 @@ const routes = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/user-management',
|
||||
component: MainLayout,
|
||||
meta: { requiresAuth: true },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'UserManagement',
|
||||
component: UserManagementView
|
||||
}
|
||||
]
|
||||
},
|
||||
// 捕获所有未匹配的路由
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
@@ -114,15 +146,18 @@ const router = createRouter({
|
||||
})
|
||||
|
||||
// 路由守卫
|
||||
router.beforeEach((to, from, next) => {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const authStore = useAuthStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
console.log('路由导航:', {
|
||||
to: to.path,
|
||||
from: from.path,
|
||||
fullPath: to.fullPath,
|
||||
requiresAuth: to.meta.requiresAuth,
|
||||
isAuthenticated: authStore.isAuthenticated
|
||||
requiresUserAuth: to.meta.requiresUserAuth,
|
||||
isAuthenticated: authStore.isAuthenticated,
|
||||
isUserAuthenticated: userStore.isAuthenticated
|
||||
})
|
||||
|
||||
// 防止重定向循环:如果已经在目标路径,直接放行
|
||||
@@ -130,9 +165,28 @@ router.beforeEach((to, from, next) => {
|
||||
return next()
|
||||
}
|
||||
|
||||
// 检查用户认证状态
|
||||
if (to.meta.requiresUserAuth) {
|
||||
if (!userStore.isAuthenticated) {
|
||||
// 尝试检查本地存储的认证信息
|
||||
const isUserLoggedIn = await userStore.checkAuth()
|
||||
if (!isUserLoggedIn) {
|
||||
return next('/user-login')
|
||||
}
|
||||
}
|
||||
return next()
|
||||
}
|
||||
|
||||
// API Stats 页面不需要认证,直接放行
|
||||
if (to.path === '/api-stats' || to.path.startsWith('/api-stats')) {
|
||||
next()
|
||||
} else if (to.path === '/user-login') {
|
||||
// 如果已经是用户登录状态,重定向到用户仪表板
|
||||
if (userStore.isAuthenticated) {
|
||||
next('/user-dashboard')
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
} else if (to.meta.requiresAuth && !authStore.isAuthenticated) {
|
||||
next('/login')
|
||||
} else if (to.path === '/login' && authStore.isAuthenticated) {
|
||||
|
||||
Reference in New Issue
Block a user