功能:登录成功后判断账号密码是否是弱密码,弱密码的话就强制出来一个修改密码的弹窗,不是弱密码就正常登录
登录一般分为两种,一直是登录成功后直接跳到首页菜单,一种是上一次退出时在那个菜单,这一次登录就是那个菜单
注意:像密码这种敏感的数据一定不要用localStorage进行存储,不安全
一、首页菜单
这种是最简单的,直接vuex存储登录密码,在首页获取密码,判断是否弱密码,出来弹窗
二、动态菜单
动态菜单因为登录进来的菜单可以是任何一个菜单,所以操作不能放在其他菜单,只能先在登录菜单处理,我的想法是在登录成功后通过vuex存储数据,然后再APP.vue页面加一个弹窗组件,根据密码是否弱密码看弹窗出不出来
下面这种方式完成后,后期测试在测试的时候提出了问题,如果在这个弹窗出来的时候直接把这个系统关闭,再重新打开,这时候就会跳过登录页面,直接回到到系统里面,会造成两个问题,1.原密码在vuex中拿不到,没办法校验,2.从路由走跳到登录页面,弹窗仍然会出现
解决方式: 1.前端不做原密码验证,直接点击确定的时候后端提示
2.通过路由判断,到登录页chakngedialogview为true,其他页面从localStorage中获取
1.1登录页面(login.vue)
登录成功后,离开当前路由会直接调用 beforeDestroy销毁,所以在beforeDestroy种判断是否弱密码,并将数据存储在vuex中
beforeDestroy(){
var mediumRegex = new RegExp("^(?=.{8,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[a-z])(?=.*\\W))|((?=.*[0-9])(?=.*\\W))|((?=.*[A-Z])(?=.*\\W))).*$", "g");
if (!mediumRegex.test(this.loginForm.pwd)){
this.chakngedialogview=true
}
//不在vuex中传值了
// var passwordverifiers={
// chakngedialogview:this.chakngedialogview,
// loginFormpwd:this.loginForm.pwd,
// }
localStorage.setItem('chakngedialogview', this.chakngedialogview)
// this.$store.dispatch('user/changeloginFormPwd', passwordverifiers );
},
mediumRegex 为密码校验的规则
chakngedialogview true 判断是弱密码,弹窗出来,false,弹窗不出来
loginFormpwd 登录账号的密码
localStorage 在内存中存储chakngedialogview ,后面会有解释
this.$store.dispatch('user/changeloginFormPwd', passwordverifiers ); vuex存数据方式看
http://t.csdn.cn/8AwCv 里面有介绍
1.2修改密码弹窗的页面 (Password-modification.vue)
<template>
<div>
<el-dialog
title="修改密码"
:visible.sync="dialogVisible"
width="30%"
:showClose="false"
class="bim-dialog"
>
<el-form
ref="formPwd"
:model="formPwd"
:rules="rules1"
label-width="100px"
:hide-required-asterisk="false"
>
<div class="passtext">
您好!您的密码存在安全隐患,请您修改密码后再使用!
</div>
<el-form-item label="旧密码:" prop="oldpwd">
<el-input
v-model="formPwd.oldpwd"
class="input"
clearable
show-password
></el-input>
</el-form-item>
<el-form-item label="新密码:" prop="newpwd">
<el-input
class="input"
v-model="formPwd.newpwd"
clearable
show-password
>
</el-input>
</el-form-item>
<el-form-item label="确认密码:" prop="newpwd2">
<el-input
class="input"
v-model="formPwd.newpwd2"
@blur="checkSame"
clearable
show-password
>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="save" class="save">保存</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
import { UpdateUserPwd } from "@/api/user";
export default {
props: ["userId"],
watch: {
$route: "getPath",
},
data() {
var checkPassWord = (rule, value, callback) => {
var mediumRegex = new RegExp(
"^(?=.{8,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[a-z])(?=.*\\W))|((?=.*[0-9])(?=.*\\W))|((?=.*[A-Z])(?=.*\\W))).*$",
"g"
);
if (!mediumRegex.test(value)) {
callback(
new Error(
"请至少使用大小写字母、数字、符号两种类型组合的密码,长度至少为8位。"
)
);
} else if (value === "bimtech0925@#") {
callback(new Error("该密码为弱密码,不能使用这个密码."));
} else {
callback();
}
};
var checkRepassWord = (rule, value, callback) => {
if (value !== this.formPwd.newpwd) {
callback(new Error("两次输入新密码不一致,请重新输入。"));
} else {
callback();
}
};
return {
dialogVisible: false,
formPwd: {
oldpwd: "",
newpwd: "",
newpwd2: "",
},
rules1: {
oldpwd: [{ required: true, message: "请填写密码", trigger: "blur" }],
newpwd: [
{ validator: checkPassWord, trigger: "blur" },
{ required: true, message: "请填写密码", trigger: "blur" },
],
newpwd2: [
{ validator: checkRepassWord, trigger: "blur" },
{ required: true, message: "请填写密码", trigger: "blur" },
],
},
};
},
methods: {
getPath() {
if (this.$route.path === "/account/login") {
this.dialogVisible = false;
} else {
this.dialogVisible = JSON.parse(
localStorage.getItem("chakngedialogview")
);
}
},
checkSame() {
if (this.formPwd.newpwd == this.formPwd.newpwd2) {
} else {
this.$message.error("两次输入新密码不一致,请重新输入");
}
},
save() {
this.$refs.formPwd.validate((valid) => {
if (valid) {
UpdateUserPwd({
userId: this.userId,
newPwd: this.formPwd.newpwd,
oldPwd: this.formPwd.oldpwd,
}).then((res) => {
if (res.IsSucceed) {
this.$message({
message: "密码修改成功",
type: "success",
});
this.dialogVisible = false;
localStorage.setItem("chakngedialogview", "false");
this.$refs.formPwd.resetFields();
} else {
this.$message.error("修改密码失败");
}
});
this.formPwd.oldpwd = "";
this.formPwd.newpwd = "";
this.formPwd.newpwd2 = "";
}
});
},
},
};
</script>
<style lang="scss" scoped>
.input {
width: 70%;
}
.el-form-item {
margin-top: 20px;
}
.passtext {
margin-bottom: 20px;
font-size: 15px;
color: rgb(2 17 47 / 65%);
font-weight: bold;
font-family: "SIYUANHEITI";
}
.bim-dialog {
.el-dialog {
border-radius: 5px !important;
.el-dialog__header {
background-color: #298dff !important;
border-radius: 5px 5px 0 0 !important;
height: 42px;
padding: 10px 15px;
.el-dialog__title {
color: white;
font-family: "微软雅黑";
}
.el-dialog__headerbtn {
top: 15px;
.el-dialog__close {
color: white;
}
}
}
}
}
.save {
float: right;
}
</style>
:hide-required-asterisk="false" 因为使用的是自定义的校验规则,所以标签前面的红色星号不显示,这时候使用 hide-required-asterisk
required 记得写
1.3在App.vue中添加组件 modification
<template>
<div id="app">
<router-view />
<modification :userId="userId"></modification>
</div>
</template>
import modification from '@/views/login/Password-modification.vue'
import { mapGetters } from 'vuex'
export default {
components: {
modification
},
name: 'App',
computed: {
...mapGetters(['roles','userId'])
},
这种方式目前能实现,但是如果直接刷新页面,会造成vuex中存储的数据丢失,导致弹窗 不出来,但我这边需要是强制修改密码的,所以我查了一些,要不然就是把数据存到localStorage中,但是密码是不能这样存的,要不然就是使用第三方库指定需要持久化的state
我使用的是把判断是不是弱密码这个字段存到localStorage,这样每次刷新,都会从内存中获取chakngedialogview,弹窗就不会消失,注意,在密码修改完后要把chakngedialogview改为false
2.1在实现这个功能时我想过在beforeDestroy使用element 的MessageBox 弹框,但是因为时修改密码的,要做校验,素所以使用this.$prompt
但是这个只能有一个输入框的校验,而且尽管有校验 ,但是密码框是需要有小眼睛的显示和隐藏的,这上面没有,后来想着用this.$msgbox,做自定义的内容,但是这样同样没有小眼睛,而且校验不好做,所以就放弃了