锁屏功能
概述
Naive Admin Max 内置了完整的锁屏系统,支持一键锁屏、服务端密码校验解锁、可选本地 PIN 快捷解锁,以及空闲自动锁定。
一键锁屏
用户可通过顶栏的「锁定屏幕」按钮一键锁定当前会话。锁定后,Layout 内的所有业务内容会被卸载,仅显示锁屏界面。
typescript
const lockStore = useLockStore()
// 锁定屏幕
lockStore.lock()解锁方式
服务端校验(默认)
默认解锁方式为输入登录密码,由服务端接口(verify-password)校验。密码依据 Token 识别会话用户,登录密码不在前端存储或比对。
typescript
// 解锁(服务端校验)
await lockStore.unlock(password)本地 PIN 快捷解锁(可选)
用户可以在锁屏界面设置一个可选 PIN,仅存储散列值,用于本地快捷解锁。一经设置即记住,无需每次重设。
typescript
// 设置本地 PIN
await lockStore.setPin(pin)
// 使用 PIN 解锁
await lockStore.unlockWithPin(pin)PIN 存储安全
PIN 仅以散列形式存储在 localStorage 中,不会上传服务端。设置 PIN 后,解锁界面会优先显示 PIN 输入框。
空闲自动锁定
锁屏支持配置空闲超时自动锁定。当用户在设定时间内无任何操作(键盘/鼠标),系统自动触发锁屏。
typescript
// 在 settingsStore 中配置
settingsStore.setIdleTimeout(300) // 300 秒无操作自动锁定空闲检测
空闲检测基于 mousemove、keydown、click 等事件。切换到其他应用程序不重置计时器。
安全机制
v-if 卸载,非遮罩
锁屏时在 Layout 内直接卸载鉴权内容(v-if 取代整个外壳),而非盖一层遮罩。这意味着:
- 页面上不存在被隐藏的业务内容
- 「审查元素删除遮罩节点」的攻击方式无法绕过
- 背后无任何 DOM 内容可供窥探
锁屏作用范围
- 锁屏只在登录后的 Layout 鉴权区域内生效
- 登录页、异常页等公共页(静态路由,不挂 Layout)不受影响
- 重新登录视为新会话,会清除残留锁定
安全边界
重要提醒
纯前端锁屏不是真正的访问控制:
- 持有 DevTools 的人仍可改写
localStorage中的锁定标记并刷新绕过 - 会话 Token 始终有效,不会被锁屏使 Token 失效
若需真正的锁屏安全,必须由服务端在锁定时挂起会话/使 Token 失效,并在解锁时重新鉴权。
Token 存储安全
Token 默认存于 localStorage,便于前后端分离与跨标签共享,但对 XSS 不设防。安全等级要求更高时,建议:
- 改由后端下发
HttpOnly+Secure+SameSite的 Cookie - JS 无法读取 Cookie 内容
- 前端不再手动管理 Token
- 开启
VITE_WITH_CREDENTIALS让请求自动携带 Cookie - 由后端做 CSRF 防护