【Ruoyi管理后台】用户登录强制修改密码 这篇文章已经实现了这个需求,因为个人业务中强制改密页面是进入系统且浮动于其他页面上方,进入强制改密页面的同时其他页面会向后台请求,如果清空token后会造成其他的请求失败。本文整体步骤与参考博文一致,详细步骤请参考【Ruoyi管理后台】用户登录强制修改密码 这篇文章,本文只是对某些方法进行了简单修改,进入强制改密页面时不清空token,使用Vue的路由守卫来拦截未修改密码的用户访问系统的特定页面。
一、login.vue页面修改
调整 handleLogin 函数,不必暂存token,而是存储res_code和rest_sign。
javascript
this.$store.dispatch("Login", this.loginForm).then((res) => {
if (res.res_code && res.res_code === 1001) {// 判断到后端接口返回的重置密码标识码
// 设置res_code与res_sign,守卫路由获取判断使用
localStorage.setItem("res_code", 1001);
localStorage.setItem("res_sign", response.reset_sign);
// 重定向到重置密码页,并带上校验参数
this.redirect = '/reset?' + 'sign=' + res.reset_sign + '&username=' + this.loginForm.username;
}
this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
}).catch(() => {
this.loading = false;
if (this.captchaOnOff) {
this.getCode();
}
});
二、强制改密页面修改
强制改密页面对博文中页面进行了简单修改,进入页面后不用清空token,增加了统一的关闭窗口方法closeWin,修改成功与取消修改时清空设置内容与token,跳转到登录页面。
html
<template>
<el-dialog :close-on-click-modal="false" title="密码过期,请修改密码" :visible.sync="thisVisible" width="600px" append-to-body :show-close="false">
<el-form ref="resetForm" :model="resetForm" :rules="secretRules" label-width="80px">
<el-row>
<el-col :span="18">
<el-form-item label="旧密码" prop="oldPassword">
<el-input v-model="resetForm.oldPassword" placeholder="请输入旧密码" type="password" :type="oldflagType" maxlength="20" auto-complete="off">
<i slot="suffix"
:class="this.oldflag?'mdi mdi-eye':'mdi mdi-eye-off'"
style="margin-top: 8px;font-size: 18px;"
@click="getoldFlag()"></i>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="18" style="margin-top: 5px">
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="resetForm.newPassword" placeholder="请输入新密码" type="password" :type="flagType" maxlength="20" auto-complete="off">
<i slot="suffix"
:class="this.flag?'mdi mdi-eye':'mdi mdi-eye-off'"
style="margin-top: 8px;font-size: 18px;"
@click="getFlag()"></i>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="18" style="margin-top: 5px">
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="resetForm.confirmPassword" placeholder="请再次输入新密码" type="password" :type="reflagType" maxlength="20" auto-complete="off">
<i slot="suffix"
:class="this.reflag?'mdi mdi-eye':'mdi mdi-eye-off'"
style="margin-top: 8px;font-size: 18px;"
@click="getreFlag()"></i>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="closeWin" >取 消</el-button>
</div>
</el-dialog>
</template>
<script>
import { resetUserProfilePwd } from "@/api/system/user";
import { setToken } from '@/utils/auth'
import { updateUserPwd } from "@/api/system/user";
import { getCodeImg } from "@/api/login";
import {MessageBox} from "element-ui";
import store from "@/store/store";
export default {
name: 'serviceDialog',
watch:{
sdVasible:{
handler(newValue){
this.thisVisible = true;
}
}
},
data() {
const equalToPassword = (rule, value, callback) => {
if (this.resetForm.newPassword !== value) {
callback(new Error("两次输入的密码不一致"));
} else {
// const reg = /^(?![A-z0-9]+$)(?![A-z~!@#$%^&*()_+]+$)(?![0-9~!@#$%^&*()_+]+$)([A-z0-9~!@#$%^&*()_+]{12,})/g
// if (!reg.test(value)) {
// callback(new Error("输入的密码必须包含数字、大小写字母、符号"));
// }
callback();
}
};
return {
oldflag: false,
oldflagType: 'password',
flag: false,
flagType: 'password',
reflag: false,
reflagType: 'password',
thisVisible:true,
resetForm: {
username: "",
oldPassword: "",
newPassword: "",
confirmPassword: "",
code: "",
sign: "",
uuid: ""
},
serviceSelectList: [],
secretRules: {
oldPassword: [{
required: true,
message: '请输入旧密码',
trigger: 'blur'
}],
newPassword: [
{ required: true, message: "新密码不能为空", trigger: "blur" },
{ pattern: /(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[^a-zA-Z0-9]).{8,20}/,
message: '新密码长度必须介于 8 和 20 之间,并且包含大写字母、小写字母、数字、特殊字符', trigger: "blur" }
],
confirmPassword: [
{ required: true, message: "再次输入新密码", trigger: "blur" },
{ required: true, validator: equalToPassword, trigger: "blur" },
{ pattern: /(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[^a-zA-Z0-9]).{8,20}/,
message: '新密码长度必须介于 8 和 20 之间,并且包含大写字母、小写字母、数字、特殊字符', trigger: "blur"
}
]
}
}
},
mounted() {
// 先清除token,防止回退后能直接登录,从而绕过强制重置密码的逻辑
//setToken('');
// 设置标志位,其他页面拿到这个值后不再向后端发送请求
//localStorage.setItem("res_code", 1001);
// 获取当前链接的参数
const params = this.$route.query;
this.resetForm.sign = params.sign;
this.resetForm.username = params.username;
this.token = params.token;
},
methods: {
getFlag(){
this.flag = !this.flag;
this.flagType = this.flag?'text':'password'
},
getoldFlag(){
this.oldflag = !this.oldflag;
this.oldflagType = this.oldflag?'text':'password'
},
getreFlag(){
this.reflag = !this.reflag;
this.reflagType = this.reflag?'text':'password'
},
closeWin() {
this.resetForm={
username: "",
oldPassword: "",
newPassword: "",
confirmPassword: "",
code: "",
sign: "",
uuid: ""
},
this.$emit('closeWin');
//删除登录成功设置的token
//localStorage.removeItem("reset_token");
localStorage.removeItem("res_code");
localStorage.removeItem("res_sign");
//清除token,强制登录
setToken("")
// 跳转到登录页
//this.$router.push("/authentication/FullLogin");
this.$router.push({ path: "/fulllogin" }).catch(() => {});
},
submitForm(){
this.$refs.resetForm.validate(valid => {
if (valid) {
this.loading = true;
resetUserProfilePwd(this.resetForm).then(response => {
if(response.code=='200') {
MessageBox.confirm('修改成功,新密码是:' + this.resetForm.newPassword, '系统提示', {
confirmButtonText: '重新登录',
showCancelButton: false, // 关闭取消按钮
//cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
this.closeWin()
}).catch(() => {
});
}else{
this.$message.success("修改失败" );
}
}).catch(() => {
this.loading = false;
})
}
});
}
}
};
</script>
三、重点:增加守卫路由
使用Vue的路由守卫来拦截密码过期未修改的用户访问系统的特定页面。在用户尝试访问系统的任何页面时,检查用户的密码过期状态,如果用户未修改,则直接显示强制改密页面。
在router.js中增加beforeEach,根据密码状态过滤访问页面,防止用户绕过强制改密页面。
javascript
router.beforeEach((to, from, next) => {
const token = getToken();
const res_code = localStorage.getItem("res_code");
const res_sign = localStorage.getItem("res_sign");
const username = store.state.user.name
if(token){
if(to.name!=='resetPwd' && res_code==='1001'){
// 重定向到强制改密页面
next({ path: '/resetPwd?' + 'sign=' + res_sign+ '&username=' + username});
}
else {
next(); // 继续正常的路由
}
}else{
next(); // 继续正常的路由
}
});
四、参考文章
五、致谢
最后感谢博主reui-CSDN博客,以及博主的答疑。