✨ 新增功能: - 全局路由守卫模块 (route-guard.js) - 多层次权限验证 (登录状态+Token存在+Token过期检查) - 自动拦截机制 (页面级+跳转级+HTTP级+应用级) - 401响应自动处理和跳转 - 路由守卫测试页面 🔧 技术实现: - checkPageAccess() 全局页面权限检查 - guardedNavigate/guardedSwitchTab 带权限检查的跳转 - handleUnauthorized() HTTP拦截器401处理 - 公开页面配置管理 - 优雅的错误提示和跳转逻辑 📱 页面集成: - App.vue 初始化路由守卫 - profile/workbench 页面添加权限检查 - index 页面优化跳转逻辑 - 新增测试页面验证功能 📚 文档完善: - 移动端路由守卫使用指南 - 详细的变更记录和技术说明 - 最佳实践和注意事项 🎯 核心效果: 用户登录失效或未登录时,访问任何需要权限的页面都自动跳转到登录页,提升安全性和用户体验。
281 lines
6.2 KiB
Markdown
281 lines
6.2 KiB
Markdown
# 移动端路由守卫使用指南
|
||
|
||
## 📋 概述
|
||
|
||
移动端路由守卫是一个全局的权限控制系统,确保用户未登录或登录失效时,访问需要权限的页面会自动跳转到登录页。
|
||
|
||
## 🎯 核心功能
|
||
|
||
### 1. 自动权限检查
|
||
|
||
- **页面加载时检查** → `onLoad()` 生命周期
|
||
- **页面显示时检查** → `onShow()` 生命周期
|
||
- **页面跳转前检查** → 使用守卫跳转方法
|
||
- **HTTP 请求拦截** → 401 响应自动处理
|
||
|
||
### 2. 多层次验证
|
||
|
||
- ✅ 检查登录状态 `userStorage.isLoggedIn()`
|
||
- ✅ 检查 Token 存在 `userStorage.getToken()`
|
||
- ✅ 检查 Token 过期 `userState.checkTokenExpiration()`
|
||
- ✅ 区分公开页面和受保护页面
|
||
|
||
### 3. 优雅的用户体验
|
||
|
||
- 🎨 友好的错误提示
|
||
- 🎨 自动清理失效信息
|
||
- 🎨 延迟跳转确保提示显示
|
||
- 🎨 使用 `reLaunch` 清除页面栈
|
||
|
||
## 🔧 使用方法
|
||
|
||
### 在页面中使用
|
||
|
||
```javascript
|
||
<script>
|
||
import { checkPageAccess } from '@/utils/route-guard';
|
||
|
||
export default {
|
||
onLoad() {
|
||
// 页面加载时检查权限
|
||
if (!checkPageAccess()) {
|
||
return; // 权限检查失败,自动跳转登录页
|
||
}
|
||
|
||
// 页面初始化逻辑
|
||
this.initPageData();
|
||
},
|
||
|
||
onShow() {
|
||
// 页面显示时再次检查权限(防止后台切换回来时失效)
|
||
if (!checkPageAccess()) {
|
||
return;
|
||
}
|
||
|
||
// 刷新页面数据
|
||
this.refreshData();
|
||
},
|
||
|
||
methods: {
|
||
initPageData() {
|
||
// 需要登录权限的初始化逻辑
|
||
},
|
||
|
||
refreshData() {
|
||
// 需要登录权限的数据刷新逻辑
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
### 带权限检查的页面跳转
|
||
|
||
```javascript
|
||
<script>
|
||
import { guardedNavigate, guardedSwitchTab } from '@/utils/route-guard';
|
||
|
||
export default {
|
||
methods: {
|
||
// 普通页面跳转
|
||
goToProfile() {
|
||
guardedNavigate('/pages/profile/index');
|
||
},
|
||
|
||
// Tab页面切换
|
||
switchToWorkbench() {
|
||
guardedSwitchTab('/pages/workbench/index');
|
||
},
|
||
|
||
// 带参数跳转
|
||
goToDetail(id) {
|
||
guardedNavigate(`/pages/detail/index?id=${id}`);
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
### 使用页面混入(可选)
|
||
|
||
```javascript
|
||
<script>
|
||
import { routeGuardMixin } from '@/utils/route-guard';
|
||
|
||
export default {
|
||
// 使用混入,自动添加权限检查
|
||
mixins: [routeGuardMixin],
|
||
|
||
onLoad() {
|
||
// 混入会自动调用权限检查
|
||
// 这里只需要写业务逻辑
|
||
this.loadData();
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
## ⚙️ 配置说明
|
||
|
||
### 公开页面配置
|
||
|
||
在 `mobile/src/utils/route-guard.js` 中配置无需登录的页面:
|
||
|
||
```javascript
|
||
// 无需登录验证的页面列表
|
||
const PUBLIC_PAGES = [
|
||
'/pages/login/index', // 登录页
|
||
'/pages/index/index', // 首页(功能受限但可访问)
|
||
];
|
||
```
|
||
|
||
### 自定义登录页路径
|
||
|
||
```javascript
|
||
// 登录页路径
|
||
const LOGIN_PAGE = '/pages/login/index';
|
||
```
|
||
|
||
## 🧪 测试功能
|
||
|
||
访问测试页面验证路由守卫功能:
|
||
|
||
```
|
||
页面路径: /pages/test-route/index
|
||
```
|
||
|
||
测试页面提供:
|
||
|
||
- 📊 实时登录状态显示
|
||
- 🔧 测试按钮(清除 Token、跳转等)
|
||
- 📋 详细的操作日志
|
||
- 🎯 权限检查结果验证
|
||
|
||
## 🔄 工作流程
|
||
|
||
### 权限检查流程
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[页面访问] --> B{是否公开页面?}
|
||
B -->|是| C[允许访问]
|
||
B -->|否| D{用户已登录?}
|
||
D -->|否| E[跳转登录页]
|
||
D -->|是| F{Token存在?}
|
||
F -->|否| E
|
||
F -->|是| G{Token未过期?}
|
||
G -->|否| E
|
||
G -->|是| C
|
||
```
|
||
|
||
### HTTP 拦截流程
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[API请求] --> B[发送请求]
|
||
B --> C{响应状态}
|
||
C -->|200| D[正常处理]
|
||
C -->|401| E[清除登录信息]
|
||
E --> F[显示提示]
|
||
F --> G[跳转登录页]
|
||
```
|
||
|
||
## 📝 最佳实践
|
||
|
||
### 1. 页面权限设计原则
|
||
|
||
- **最小权限原则**:只有必要的页面才需要登录
|
||
- **用户友好原则**:首页等入口页面可以部分访问
|
||
- **安全优先原则**:敏感操作必须验证权限
|
||
|
||
### 2. 错误处理建议
|
||
|
||
```javascript
|
||
onLoad() {
|
||
try {
|
||
if (!checkPageAccess()) {
|
||
return;
|
||
}
|
||
|
||
// 业务逻辑
|
||
await this.loadUserData();
|
||
|
||
} catch (error) {
|
||
console.error('页面初始化失败:', error);
|
||
uni.showToast({
|
||
title: '页面加载失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 性能优化建议
|
||
|
||
- 权限检查放在业务逻辑之前
|
||
- 避免在权限检查失败后继续执行后续逻辑
|
||
- 合理使用页面缓存减少重复检查
|
||
|
||
## 🚨 注意事项
|
||
|
||
### 1. 公开页面处理
|
||
|
||
```javascript
|
||
// ❌ 错误:在公开页面中强制检查权限
|
||
onLoad() {
|
||
if (!checkPageAccess()) return; // 首页不应该强制登录
|
||
}
|
||
|
||
// ✅ 正确:区分功能的权限要求
|
||
onLoad() {
|
||
// 首页可以访问,但部分功能需要登录
|
||
this.checkLoginForFeatures();
|
||
}
|
||
```
|
||
|
||
### 2. 避免循环跳转
|
||
|
||
```javascript
|
||
// ❌ 错误:在登录页中调用权限检查
|
||
// pages/login/index.vue
|
||
onLoad() {
|
||
checkPageAccess(); // 会导致循环跳转
|
||
}
|
||
|
||
// ✅ 正确:登录页无需权限检查
|
||
onLoad() {
|
||
// 直接执行登录页逻辑
|
||
}
|
||
```
|
||
|
||
### 3. Token 刷新处理
|
||
|
||
```javascript
|
||
// 建议在HTTP拦截器中处理Token刷新
|
||
// 避免在页面级别处理复杂的Token逻辑
|
||
```
|
||
|
||
## 🔗 相关文档
|
||
|
||
- [移动端用户管理工具](./移动端用户管理工具使用指南.md)
|
||
- [移动端 API 请求规范](./移动端API请求规范.md)
|
||
- [移动端开发规范总结](./移动端开发规范总结.md)
|
||
|
||
## 💡 常见问题
|
||
|
||
### Q: 如何添加新的公开页面?
|
||
|
||
A: 在 `route-guard.js` 的 `PUBLIC_PAGES` 数组中添加页面路径。
|
||
|
||
### Q: 权限检查失败但没有跳转到登录页?
|
||
|
||
A: 检查控制台日志,确认 `reLaunch` 是否执行成功,必要时检查页面路径配置。
|
||
|
||
### Q: 如何自定义权限检查逻辑?
|
||
|
||
A: 可以扩展 `checkPageAccess` 函数,添加更复杂的权限验证逻辑。
|
||
|
||
### Q: 在什么情况下需要使用 `routeGuardMixin`?
|
||
|
||
A: 当页面逻辑复杂,希望自动化权限检查时使用,但通常建议手动调用以保持代码清晰。
|