【Vue管理后台】用户登录强制修改密码

【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(); // 继续正常的路由
    }

});

四、参考文章

【Ruoyi管理后台】用户登录强制修改密码

五、致谢

最后感谢博主reui-CSDN博客,以及博主的答疑。

相关推荐
梦想的旅途22 分钟前
企业微信消息回调开发指南:如何实时接收并处理企微消息?
前端·机器人·自动化·企业微信
何中应3 分钟前
CentOS7安装高版本Node.js
前端·centos·node.js
じ星不离月か4 分钟前
【记录】 跑马灯无限滚动
前端·css·跑马灯·无限滚动
周淳APP4 分钟前
【HTTP1、HTTP2、HTTP3】
前端·网络·网络协议·http
夫唯不争,故无尤也8 分钟前
原始文档元数据metadata
java·前端·javascript·sql
wefly20179 分钟前
无需安装的 M3U8 在线播放器,快速实现 HLS 流预览与调试
java·开发语言·python·开发工具
恋猫de小郭10 分钟前
Flutter 3.41 iOS 键盘负优化:一个代码洁癖引发的负优化
android·前端·flutter
胡楚昊12 分钟前
XSS LAB通关笔记(1-16)
前端·笔记·xss
新晨43712 分钟前
cursor轻松实现代码搬迁
前端·ai编程·cursor
We་ct13 分钟前
LeetCode 211. 添加与搜索单词 - 数据结构设计:字典树+DFS解法详解
开发语言·前端·数据结构·算法·leetcode·typescript·深度优先