fix(auth): 激活页清除残留登录态 + 全站密码框显式 autocomplete 语义
R61/R62:两个独立缺陷(测试人员反馈「设置密码框已有 123456 + 激活后直接进管理后台」)。 ① 激活后进管理后台 —— 安全缺陷(公用电脑 = 越权) Activate.vue 激活成功与「返回登录」都跳 /login,而 router guard (router/index.js:203-222)见到 isLoggedIn && role==='admin' 会重定向到 /admin。 浏览器残留 admin 登录态时(测试人员刚用 admin 操作过后台),考生会被 直接送进管理后台;且 /api/admin/* 全部挂 adminAuth(router.js:25) ⇒ 残留 token 有效时管理接口真能调。 修法:激活页按「未登录」语义处理 —— onMounted 与激活成功后均 clearAuth()。 ② 设置密码页密码框被浏览器预填 密码框未显式声明 autocomplete,而 EP el-input 该 prop 默认 "off", Chromium 对 type=password 会忽略 off,改用该站点已保存凭据自动填充。 密码规则仅 min:6 ⇒ "123456" 恰好合法 ⇒ 用户不知情下即把密码设成 123456。 修法:6 个密码框显式声明语义 —— 设密码/重置密码 new-password(4 处), 登录 current-password(2 处,含管理员 tab)。 验证:真浏览器 21/21 断言通过(含「残留 admin 态直接访问 /login 必跳 /admin」 对照臂,证明断言非恒真);TDZ 扫描 PASS(26 文件);权威脚本构建 157 文件 / 70 .gz;生产零中断上线(MainPID/NRestarts/ActiveEnterTimestamp 未变)。
This commit is contained in:
@@ -149,6 +149,7 @@
|
||||
<el-input
|
||||
v-model="step3Form.password"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
placeholder="请设置登录密码(至少6位)"
|
||||
size="large"
|
||||
show-password
|
||||
@@ -159,6 +160,7 @@
|
||||
<el-input
|
||||
v-model="step3Form.confirmPassword"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
placeholder="请再次输入密码"
|
||||
size="large"
|
||||
show-password
|
||||
@@ -211,8 +213,14 @@ import { ElMessage } from 'element-plus'
|
||||
import { ArrowLeft, HomeFilled, Refresh } from '@element-plus/icons-vue'
|
||||
import * as authApi from '@/api/auth'
|
||||
import { showTestSmsCode } from '@/utils/testSms'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const router = useRouter()
|
||||
// 激活页语义 = 未登录。必须主动清除浏览器中可能残留的登录态:
|
||||
// 否则激活成功/点「返回登录」跳 /login 时,router guard(router/index.js:203-222)
|
||||
// 见到 isLoggedIn && role==='admin' 会把用户重定向进 /admin —— 公用电脑上
|
||||
// 前一位管理员未退出时,下一位激活的考生会被直接送进管理后台且接口权限可用(R61)。
|
||||
const authStore = useAuthStore()
|
||||
|
||||
// ==================== 状态 ====================
|
||||
|
||||
@@ -408,6 +416,9 @@ async function handleActivate() {
|
||||
smsCode: step2Form.smsCode,
|
||||
})
|
||||
ElMessage.success('账号激活成功!请登录参赛')
|
||||
// 兜底再清一次(R61):确保跳转瞬间 localStorage 内无残留登录态,
|
||||
// 否则 /login 的守卫会把用户送进 /admin。
|
||||
authStore.clearAuth()
|
||||
// 跳转到登录页
|
||||
setTimeout(() => {
|
||||
router.push('/login')
|
||||
@@ -452,6 +463,9 @@ function startSmsCountdown() {
|
||||
// ==================== 生命周期 ====================
|
||||
|
||||
onMounted(() => {
|
||||
// 进入激活页即按「未登录」处理(R61):清掉残留 token/user,
|
||||
// 覆盖两条会跳 /login 的路径 —— ①本页「返回登录」按钮 ②激活成功后的跳转。
|
||||
authStore.clearAuth()
|
||||
refreshCaptcha()
|
||||
})
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
<el-input
|
||||
v-model="step3Form.password"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
placeholder="请设置新密码(至少6位)"
|
||||
size="large"
|
||||
show-password
|
||||
@@ -149,6 +150,7 @@
|
||||
<el-input
|
||||
v-model="step3Form.confirmPassword"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
placeholder="请再次输入新密码"
|
||||
size="large"
|
||||
show-password
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
<el-input
|
||||
v-model="contestantForm.password"
|
||||
type="password"
|
||||
autocomplete="current-password"
|
||||
placeholder="请输入密码"
|
||||
:prefix-icon="Lock"
|
||||
size="large"
|
||||
@@ -103,6 +104,7 @@
|
||||
<el-input
|
||||
v-model="adminForm.password"
|
||||
type="password"
|
||||
autocomplete="current-password"
|
||||
placeholder="请输入密码"
|
||||
:prefix-icon="Lock"
|
||||
size="large"
|
||||
|
||||
Reference in New Issue
Block a user