需求:由于项目机密性高,需要关注每个安全的问题,一般大型项目安全上的问题有很多,这次主要分析的是锁屏相关的思路和知识点。
思路:用户长时间不操作,就没有鼠标点击(window.document.onmousedown)事件、鼠标滚轮(mousewheel)事件、鼠标移动(mousemove)事件之类的,我们只需要监听这些事件,如果这些事件长时间没有触发,就说明用户长时间未操作,然后路由跳转到登录页面即可。
存储方式:sessionstorage,不用vuex的原因是防止主动刷新丢失,sessionstorage刚好就浏览器关闭就丢失。
此操作分纯前端处理和前后端处理,原则,前端能独立处理就不需要后端了。
login
//在点击登录按钮成功时, 存第一份点击的时间
sessionStorage.setItem("lastClickTime", new Date().getTime());
在app.vue主页面下,或者loyout的首页中,进行相应的操作
/*
第一步:
组件初始化加载就绑定监听点击事件,注意:addEventListener的第三个参数,这里要加上。
因为第三个参数决定了是冒泡还是捕获(false冒泡默认,true捕获),因为绑定监听点击事件,我们是在最
顶层的DOM位置进行捕获点击事件,所以第三个参数true,要加上的,这样的话,内层的任意地方的点击事件
我们就都能监听到了,然后存储一下点击的时间
*/
vue3定义几个参数
const timer = ref(null)
window.addEventListener(
"click",
() => {
// 为了方便,我们把点击事件的时间直接存到sessionStorage中去,这样方便获取比较
sessionStorage.setItem("lastClickTime", new Date().getTime());
},
true
);
},
/*
第二步:
组件初始化加载时也要绑定一个定时器,通过定时器定时轮询,去对比当前时间和上次点击的时间的差值
*/
mounted 下激活
isTimeOut()
isTimeOut() {
// 使用定时器之前,要清除一下定时器
clearInterval(this.timer);
this.timer = setInterval(() => {
let lastClickTime = sessionStorage.getItem("lastClickTime") * 1; // 把上次点击时候的字符串时间转换成数字时间
let nowTime = new Date().getTime(); // 获取当前时间
console.log("当前时间和之前点击时间", nowTime, lastClickTime);
// 假设我们需求是:5秒钟不进行点击操作,就提示登录退出
if (nowTime - lastClickTime > 1000 * 5) {
// 提示一下用户
this.$message({ type: "warning", message: "超时了,已退出登录" });
// 这里要清除定时器,结束任务
clearInterval(this.timer);
// 最后返回到登录页
this.$router.push({ path: "/login" });
}
}, 1000);
},
},
beforeDestroy() {
// 最后一步,离开页面的时候,清除一下定时器,也解绑点击事件
clearInterval(this.timer);
window.removeEventListener("click", () => {}, true);
},
};
上面是vue2的写法,下面是vue3加ts的写法,有几个坑
- onMounted(() => {
- isTimeOut();
- });
- function isTimeOut() {
- // 使用定时器之前,要清除一下定时器
- clearInterval(Number(timer));
- // clearInterval(timer);
- timer.value = window.setInterval(() => {
- // setInterval不能用 要用window.setInterval 计时器"不可分配给类型
- let lastClickTime = Number(sessionStorage.getItem("lastClickTime"));
- let nowTime = new Date().getTime(); // 获取当前时间
- if (router.currentRoute.value.name == "login") return;
- console.log("当前时间和之前点击时间", nowTime, lastClickTime);
- // 假设我们需求是:5秒钟不进行点击操作,就提示登录退出
- if (nowTime - lastClickTime > 1000 * 30 * 10) {
- clearInterval(Number(timer));
- console.log(111);
- ElMessage({
- type: "success",
- message: "长时间未操作,请重新登录"
- });
- router.push({ path: "/login" });
- }
- }, 10000);
- console.log(timer);
- }
- onUnmounted(() => {
- // 最后一步,离开页面的时候,清除一下定时器,也解绑点击事件
- clearInterval(Number(timer));
- window.removeEventListener("click", () => {}, true);
- });

确认后,把代码进行md5加密,如果安全不高的话也直接存储在vuex或者pina上,如果想加密的话要加上sessionStore或者localStore,加这些话都要求请求接口
输入后跳转到

async function confrin() {
await formRef.value.validate();//校验
dialogVisible.value = false;
// store.SET_LOCK_PASSWD(md5(FromData.lockPassword)); 先不加密
store.SET_LOCK_PASSWD(FromData.lockPassword);//存储在vuex
store.SET_LOCK();//定义islock为true,用来路由跳转做判断
setTimeout(() => {
router.push({ name: "lockPage" });
}, 100);
}
router:
if (globalStore.isLock && to.path !== "/lockPage") {
next({
path: "/lockPage"
});
NProgress.done();
return;
}

点击解锁有三个功能,进入系统就是要核对代码。这是我只拿vuex/pina存储的密码
function goSytem() {
if (!inputPassward.value) {
ElMessage({
type: "warning",
message: "请输入锁屏密码"
});
return;
}
let pwd = inputPassward.value;
// let oldPwd = localStorage.getItem("lockPasswd");
let oldPwd = globalStore.lockPasswd;
console.log(oldPwd, pwd);
if (pwd !== oldPwd) {
ElMessage({
type: "warning",
message: "请输入相同锁屏密码"
});
return;
} else {
globalStore.isLock = false;
router.push({ name: "home" });
}
}