refactor(登录认证): 重构登录认证流程并简化照片查询入口
移除照片查询页面的登录校验,改为统一由路由守卫处理 重构登录跳转逻辑,增加安全导航函数处理重定向 将token有效期从7天改为3天
Showing
3 changed files
with
36 additions
and
21 deletions
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-10-30 10:29:15 | 2 | * @Date: 2025-10-30 10:29:15 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-11-11 12:56:04 | 4 | + * @LastEditTime: 2025-11-11 22:10:22 |
| 5 | * @FilePath: /stdj_h5/src/router/index.js | 5 | * @FilePath: /stdj_h5/src/router/index.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| ... | @@ -98,14 +98,18 @@ router.beforeEach((to, from, next) => { | ... | @@ -98,14 +98,18 @@ router.beforeEach((to, from, next) => { |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | /** | 100 | /** |
| 101 | - * 访问控制:仅在进入 /studentInfo 时校验登录状态 | 101 | + * 访问控制:除首页('/')与登录页外,其余页面均需登录 |
| 102 | * 说明:优先读取 Cookie 中的 token;若不存在则回退读取本地存储 token,避免重复登录。 | 102 | * 说明:优先读取 Cookie 中的 token;若不存在则回退读取本地存储 token,避免重复登录。 |
| 103 | */ | 103 | */ |
| 104 | - const has_token_cookie = !!Cookies.get('token-stdj') | 104 | + const token_cookie = Cookies.get('token-stdj') |
| 105 | - const is_login = has_token_cookie | 105 | + const is_login = !!(token_cookie) |
| 106 | 106 | ||
| 107 | - if (to.path === '/studentInfo' && !is_login) { | 107 | + // 白名单:无需登录校验的路径 |
| 108 | - // 关键:在重定向前关闭或重置上一跳的loading,避免计数残留 | 108 | + const white_list = ['/', '/login'] |
| 109 | + const need_auth = !white_list.includes(to.path) | ||
| 110 | + | ||
| 111 | + if (need_auth && !is_login) { | ||
| 112 | + // 在重定向前关闭或重置上一跳的loading,避免计数残留 | ||
| 109 | try { | 113 | try { |
| 110 | const loading = useLoadingStore() | 114 | const loading = useLoadingStore() |
| 111 | loading.reset() | 115 | loading.reset() |
| ... | @@ -116,7 +120,6 @@ router.beforeEach((to, from, next) => { | ... | @@ -116,7 +120,6 @@ router.beforeEach((to, from, next) => { |
| 116 | return | 120 | return |
| 117 | } | 121 | } |
| 118 | 122 | ||
| 119 | - // 其他页面不做登录校验 | ||
| 120 | next() | 123 | next() |
| 121 | }) | 124 | }) |
| 122 | 125 | ... | ... |
| ... | @@ -125,7 +125,7 @@ | ... | @@ -125,7 +125,7 @@ |
| 125 | <div class="photo-section" @click="handlePhotoClick"> | 125 | <div class="photo-section" @click="handlePhotoClick"> |
| 126 | <div class="photo-content"> | 126 | <div class="photo-content"> |
| 127 | <div class="photo-title">照片查询下载</div> | 127 | <div class="photo-title">照片查询下载</div> |
| 128 | - <div class="more-button"><span class="more-text">身份验证</span></div> | 128 | + <div class="more-button"><span class="more-text">进入</span></div> |
| 129 | </div> | 129 | </div> |
| 130 | </div> | 130 | </div> |
| 131 | </div> | 131 | </div> |
| ... | @@ -184,7 +184,6 @@ import VideoPlayer from '@/components/VideoPlayer.vue' | ... | @@ -184,7 +184,6 @@ import VideoPlayer from '@/components/VideoPlayer.vue' |
| 184 | import { useTitle } from '@vueuse/core'; | 184 | import { useTitle } from '@vueuse/core'; |
| 185 | import { useRouter } from 'vue-router' | 185 | import { useRouter } from 'vue-router' |
| 186 | import { showToast } from 'vant' | 186 | import { showToast } from 'vant' |
| 187 | -import Cookies from 'js-cookie' | ||
| 188 | 187 | ||
| 189 | // 导入接口 | 188 | // 导入接口 |
| 190 | import { homePageAPI } from '@/api/index.js' | 189 | import { homePageAPI } from '@/api/index.js' |
| ... | @@ -653,16 +652,9 @@ const dismissSwipeHint = () => { | ... | @@ -653,16 +652,9 @@ const dismissSwipeHint = () => { |
| 653 | * 说明:未登录跳转登录页;已登录进入戒子信息页面。 | 652 | * 说明:未登录跳转登录页;已登录进入戒子信息页面。 |
| 654 | * @returns {void} | 653 | * @returns {void} |
| 655 | */ | 654 | */ |
| 656 | -// 登录状态获取 | ||
| 657 | -const hasLogin = computed(() => Boolean(Cookies.get('token-stdj'))) | ||
| 658 | 655 | ||
| 659 | const handlePhotoClick = () => { | 656 | const handlePhotoClick = () => { |
| 660 | - // 判断是否已登录 | 657 | + router.push('/studentInfo') |
| 661 | - if (hasLogin.value) { | ||
| 662 | - router.push('/studentInfo') | ||
| 663 | - } else { | ||
| 664 | - router.push('/login') | ||
| 665 | - } | ||
| 666 | } | 658 | } |
| 667 | </script> | 659 | </script> |
| 668 | 660 | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-11-10 18:08:59 | 2 | * @Date: 2025-11-10 18:08:59 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-11-11 15:51:10 | 4 | + * @LastEditTime: 2025-11-11 22:45:33 |
| 5 | * @FilePath: /stdj_h5/src/views/Login.vue | 5 | * @FilePath: /stdj_h5/src/views/Login.vue |
| 6 | * @Description: 登录页 | 6 | * @Description: 登录页 |
| 7 | --> | 7 | --> |
| ... | @@ -162,6 +162,24 @@ const on_send_sms = async function () { | ... | @@ -162,6 +162,24 @@ const on_send_sms = async function () { |
| 162 | } | 162 | } |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | +const safe_navigate = function () { | ||
| 166 | + // 跳转目标处理:兼容 redirect 携带 query/hash 的场景 | ||
| 167 | + // 说明:当地址形如 /login?redirect=/masters?pid=3651943 时,使用字符串导航更安全; | ||
| 168 | + // 同时解析并保留查询与哈希,避免对象形式 path 丢失查询参数。 | ||
| 169 | + const redirect_raw = String(route.query.redirect || '').trim() | ||
| 170 | + let redirect_target = '/home' | ||
| 171 | + if (redirect_raw) { | ||
| 172 | + try { | ||
| 173 | + const url = new URL(redirect_raw, window.location.origin) | ||
| 174 | + redirect_target = url.pathname + url.search + url.hash | ||
| 175 | + } catch (err) { | ||
| 176 | + // 若不是标准URL(仅相对路径),直接使用或回退到默认页 | ||
| 177 | + redirect_target = redirect_raw.startsWith('/') ? redirect_raw : '/home' | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | + router.replace(redirect_target) | ||
| 181 | +} | ||
| 182 | + | ||
| 165 | /** | 183 | /** |
| 166 | * 登录 | 184 | * 登录 |
| 167 | * @returns {Promise<void>} | 185 | * @returns {Promise<void>} |
| ... | @@ -181,10 +199,12 @@ const on_login = async function () { | ... | @@ -181,10 +199,12 @@ const on_login = async function () { |
| 181 | const { code, data } = await loginAPI({ mobile: phone.value, code: code.value }) | 199 | const { code, data } = await loginAPI({ mobile: phone.value, code: code.value }) |
| 182 | if (code) { | 200 | if (code) { |
| 183 | // 登录成功后,将token存储到cookie中 | 201 | // 登录成功后,将token存储到cookie中 |
| 184 | - Cookies.set('token-stdj', data.token, { expires: 7 }) | 202 | + Cookies.set('token-stdj', data.token, { expires: 3 }) |
| 185 | showSuccessToast('登录成功') | 203 | showSuccessToast('登录成功') |
| 186 | - // 跳转戒子详情页 | 204 | + setTimeout(() => { |
| 187 | - router.replace({ path: route.query.redirect }) | 205 | + // 登录成功后,跳转至 redirect 目标页或默认首页 |
| 206 | + safe_navigate() | ||
| 207 | + }, 1000) | ||
| 188 | } | 208 | } |
| 189 | } catch (e) { | 209 | } catch (e) { |
| 190 | showFailToast('网络异常,请稍后重试') | 210 | showFailToast('网络异常,请稍后重试') | ... | ... |
-
Please register or login to post a comment