guards.js
3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* @Date: 2025-03-20 20:36:36
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-20 10:18:33
* @FilePath: /mlaj/src/router/guards.js
* @Description: 路由守卫逻辑
*/
import { getAuthInfoAPI } from '@/api/auth'
import { wxInfo } from "@/utils/tools"
// TAG: 需要登录才能访问的路由
export const authRequiredRoutes = [
{
path: '/profile',
exact: false,
},
{
path: '/checkout',
exact: true,
},
{
path: '/activities/[^/]+/signup',
regex: true,
},
{
path: '/checkin',
exact: false,
},
{
path: '/teacher',
exact: false,
},
{
path: '/studyDetail',
exact: false,
},
]
/**
* @description 兼容旧逻辑的微信授权检查(不再自动跳转)
* @returns {boolean} 始终返回true,不在路由守卫内自动触发授权
*/
export const checkWxAuth = async () => {
// 说明:根据新业务需求,微信授权不应在路由守卫中自动触发
// 此函数保留以兼容旧代码调用,但不再进行重定向
try {
if (!import.meta.env.DEV && wxInfo().isWeiXin) {
// 仅做一次授权状态探测,避免无意义请求
await getAuthInfoAPI();
}
} catch (error) {
// 忽略授权探测错误,不影响后续流程
}
return true;
}
/**
* @description 手动发起微信授权登录(仅在用户点击微信图标时触发)
* @returns {void}
*/
/**
* @function startWxAuth
* @description 手动发起微信授权登录;使用不含 hash 的完整 URL 作为回跳参数,避免微信浏览器对 hash 的处理差异导致回跳异常。
* @returns {void}
*/
export const startWxAuth = async () => {
// 开发环境不触发微信授权
if (import.meta.env.DEV) {
// 开发环境下不触发微信授权登录
return;
}
const info = wxInfo();
// 非微信环境不进行授权跳转
if (!info.isWeiXin) {
return;
}
// 如果已授权则不跳转;否则进入授权页
try {
const { code, data } = await getAuthInfoAPI();
if (code && data.openid_has) {
return;
}
} catch (e) {
// 探测失败不影响授权流程,继续跳转
}
// 跳转到微信授权地址
const raw_url = encodeURIComponent(location.href);
const short_url = `/srv/?f=behalo&a=openid&res=${raw_url}`;
location.href = short_url;
}
// 检查用户是否已登录
/**
* @description 登录权限检查,未登录时重定向到登录页
* @param {*} to 目标路由对象
* @returns {true|Object} 允许通过或返回重定向对象
*/
export const checkAuth = (to) => {
const currentUser = JSON.parse(localStorage.getItem('currentUser'))
// 检查当前路由是否需要认证
// 方式一:白名单匹配(兼容旧逻辑)
const needAuthByList = authRequiredRoutes.some((route) => {
// 如果是正则匹配模式
if (route.regex) {
return new RegExp(`^${route.path}$`).test(to.path)
}
// 如果是精确匹配模式
if (route.exact) {
return to.path === route.path
}
// 默认前缀匹配模式
return to.path.startsWith(route.path)
})
// 方式二:读取路由元信息 requiresAuth(推荐)
// 注意:axios 拦截器中调用时,to 可能不是完整的 Route 对象,可能缺少 matched 属性
// 如果没有 matched 属性,则回退到仅依赖 path 的白名单匹配
const needAuthByMeta = to.matched
? to.matched.some(record => record.meta && record.meta.requiresAuth === true)
: false;
const needAuth = needAuthByList || needAuthByMeta
if (needAuth && !currentUser) {
// 未登录时重定向到登录页面
return { path: '/login', query: { redirect: to.fullPath } }
}
return true
}