跳到主要内容

邮轮穿舱件管理系统 - 导航守卫与权限验证机制

概述

本文档详细分析邮轮穿舱件管理系统前端应用的路由守卫实现、权限验证逻辑和访问控制机制。系统基于Vue.js框架构建,采用Vue Router进行路由管理,Vuex进行状态管理,通过全局前置守卫实现基于登录状态的路由保护。

系统架构概览

flowchart TD
A[用户访问] --> B{路由守卫检查}
B -->|需要认证| C[检查登录状态]
B -->|无需认证| D[直接访问]
C -->|已登录| E[访问目标页面]
C -->|未登录| F[重定向到登录页]
F --> G[登录验证]
G -->|成功| H[更新认证状态]
H --> E
G -->|失败| F

路由守卫实现

全局前置守卫

系统在src/router/index.js中实现了全局前置守卫router.beforeEach,负责所有路由跳转前的权限验证。

// 全局前置守卫实现
router.beforeEach((to, from, next) => {
// 检查是否为调试模式
const isDebugMode = process.env.NODE_ENV === 'development';

// 如果是调试模式,直接跳过验证
if (isDebugMode) {
console.log('Debug mode: skipping authentication check');
next();
return;
}

// 检查路由是否需要认证
const requiresAuth = to.matched.some(record => {
const meta = record.meta || {};
return Boolean(meta.requiresAuth);
});

const isAuthenticated = store.state.authenticated

if (requiresAuth && !isAuthenticated) {
// 需要认证但未登录,重定向到登录页
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
})

参考文件:

路由配置

系统路由配置采用基于元信息(meta)的权限控制策略:

// 公开路由(无需认证)
{
path: "/login",
name: "Login",
component: () => import('@/views/LoginView.vue'),
meta: { requiresAuth: false } // 明确标记为无需认证
},
{
path: "/about",
name: "About",
component: () => import('@/views/AboutView.vue'),
meta: { requiresAuth: false }
},
{
path: "/register",
name: "Register",
component: () => import('@/views/RegisterView.vue'),
meta: { requiresAuth: false }
}

// 受保护路由(默认需要认证)
{
path: "/workpiece",
name: "Workpiece",
component: () => import('@/views/workpiece/WorkpieceView.vue')
// 未设置meta.requiresAuth,默认为true
}

参考文件:

认证状态管理

Vuex Store架构

系统使用Vuex进行全局状态管理,认证相关状态定义如下:

classDiagram
class VuexStore {
+state: StoreState
+mutations: StoreMutations
+actions: StoreActions
+getters: StoreGetters
}

class StoreState {
+authenticated: boolean
+user_info: object
+user_token: string
+navigator_drawer: boolean
}

class StoreMutations {
+set_authenticated(value: boolean)
+set_user_info(value: object)
+set_user_token(value: string)
+set_navigator_drawer(value: boolean)
}

class StoreActions {
+set_authenticated(value: boolean)
+set_user_info(value: object)
+set_user_token(value: string)
+set_navigator_drawer(value: boolean)
}

class StoreGetters {
+get_authenticated(): boolean
+get_user_info(): object
+get_user_token(): string
}

VuexStore --> StoreState
VuexStore --> StoreMutations
VuexStore --> StoreActions
VuexStore --> StoreGetters

参考文件:

状态管理实现

// Vuex Store配置
export default new Vuex.Store({
state: {
navigator_drawer: false,
authenticated: false, // 认证状态
user_info: null, // 用户信息
user_token: null // 用户令牌
},
mutations: {
set_authenticated(state, value) {
state.authenticated = value
},
set_user_token(state, value) {
state.user_token = value
}
},
// ... 其他配置
})

登录认证流程

登录流程时序图

sequenceDiagram
participant U as 用户
participant L as LoginView
participant H as HTTP拦截器
participant S as 后端服务
participant R as Vue Router
participant X as Vuex Store

U->>L: 输入凭据提交登录
L->>H: 发送登录请求
H->>S: POST /token
S-->>H: 返回JWT令牌
H-->>L: 响应数据
L->>X: dispatch set_authenticated(true)
L->>X: dispatch set_user_token(token)
L->>R: 跳转到目标页面
R->>R: 路由守卫验证通过
R-->>U: 显示目标页面

登录组件实现

登录组件LoginView.vue负责处理用户认证:

// 登录提交逻辑
submit() {
if (this.$refs.form.validate() && this.turnstileToken){
http.post('/token',{
username: this.formData.username,
password: this.formData.password,
'cf-turnstile-response': this.turnstileToken
}).then(response => {
if (response.status == 200) {
let token = response.data.access_token;
Cookies.set("token", token)
this.$store.dispatch("set_authenticated", true)
this.$store.dispatch("set_user_token", token)
this.$router.push(this.$route.query.redirect || '/')
}
})
}
}

参考文件:

权限验证工具

令牌验证机制

系统提供完整的JWT令牌验证工具:

function checkAuthorizaion() {
console.log("Checking authorization");
const token = Cookies.get("token");
if (token) {
try {
const decodedToken = jwtDecode(token);
const currentTime = Date.now() / 1000;
if (decodedToken.exp > currentTime) {
sessionStorage.setItem("token", token);
return true;
} else {
return false;
}
} catch (error) {
return false;
}
} else {
return false;
}
}

参考文件:

HTTP请求拦截

系统通过axios拦截器自动附加认证令牌:

// 请求拦截器
service.interceptors.request.use(
config => {
const token = getTokenFromCookie('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
}
);

参考文件:

安全特性

人机验证集成

系统集成Cloudflare Turnstile进行人机验证:

// Turnstile初始化
initializeTurnstile() {
this.turnstileWidgetId = window.turnstile.render(this.$refs.turnstile, {
sitekey: this.turnstileSiteKey,
callback: (token) => {
this.onTurnstileCallback(token);
}
});
}

参考文件:

调试模式支持

系统支持开发环境下的调试模式,可跳过认证检查:

// 调试模式检查
const isDebugMode = process.env.NODE_ENV === 'development';
if (isDebugMode) {
console.log('Debug mode: skipping authentication check');
next();
return;
}

数据流分析

认证状态数据流

flowchart LR
A[用户登录] --> B[设置Cookie]
B --> C[更新Vuex状态]
C --> D[路由守卫检查]
D --> E[访问受保护路由]
E --> F[HTTP拦截器附加令牌]
F --> G[后端验证]
G --> H[返回数据]

令牌生命周期管理

stateDiagram-v2
[*] --> 未认证
未认证 --> 已认证: 登录成功
已认证 --> 令牌过期: 令牌过期
令牌过期 --> 未认证: 重新登录
已认证 --> 未认证: 用户登出
未认证 --> [*]

性能优化考虑

  1. 懒加载路由:所有路由组件使用动态导入,减少初始包大小
  2. 令牌缓存:令牌同时存储在Cookie和sessionStorage中,提高访问效率
  3. 条件验证:开发环境下可跳过认证检查,提高开发效率

索引

邮轮穿舱件管理系统的导航守卫机制采用了成熟的Vue.js生态技术栈,通过全局前置守卫、Vuex状态管理和HTTP拦截器的协同工作,实现了完整的权限验证体系。系统具备以下特点:

  • 灵活的权限控制:基于路由元信息的细粒度权限管理
  • 安全的认证流程:JWT令牌验证和人机验证集成
  • 良好的用户体验:智能重定向和调试模式支持
  • 可扩展的架构:模块化的设计便于后续功能扩展

该实现为系统提供了可靠的安全保障,同时保持了良好的开发体验和运行性能。

主要参考文件: