密码校验

方案二

    password: [{ required: true, validator: validatePassword, trigger: 'blur' }],
    
    export function validatePassword(rule, value, callback) {
        let strength = 10; // 1-5 weak 6-8 medium 8-10 high
        let enoughLen = value && value.length >= 8 && value.length <= 16; 
        const invalidNumberPattern = /(\d)\1\1|(?:012|123|234|345|456|567|678|789)|(?:987|876|765|654|543|432|321|210)/;
        const invalidLetterPatternL = /([a-z])\1\1|(?:abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz)|(?:zyx|yxw|xwv|wvu|vut|uts|tsr|srq|rqp|qpo|pon|onm|nml|mlk|lkj|kji|jih|ihg|hgf|gfe|fed|edc|dcb|cba)/i;
        const invalidLetterPatternU = /([A-Z])\1\1|(?:ABC|BCD|CDE|DEF|EFG|FGH|GHI|HIJ|IJK|JKL|KLM|LMN|MNO|NOP|OPQ|PQR|QRS|RST|STU|TUV|UVW|VWX|WXY|XYZ)|(?:ZYX|YXW|XWV|WVU|VUT|UTS|TSR|SRQ|RQP|QPO|PON|ONM|NML|MLK|LKJ|KJI|JIH|IHG|HGF|GFE|FED|EDC|DCB|CBA)/i;
    
        if(value) {
            // 长度小于8位
            if (value.length < 8) strength--;
            // 长度大于16位
            if (value.length > 17) strength--;
            // 没有包含数字
            if (!/\d/.test(value)) strength--;
            // 没有包含小写字母
            if (!/[a-z]/.test(value)) strength--;
            // 没有包含大写字母
            if (!/[A-Z]/.test(value)) strength--;
            // 没有包含特殊字符
            if (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(value)) strength--;
            // 是否在弱口令列表内
            if(isWeakPassword(value)) strength--;
            // 是否包含3个连续或相同数字(正序,逆序)
            if(invalidNumberPattern.test(value)) strength--;
            // 是否包含3个连续或相同小写字母(正序,逆序)
            if(invalidLetterPatternL.test(value)) strength--;
            // 是否包含3个连续或相同大写字母(正序,逆序)
            if(invalidLetterPatternU.test(value)) strength--;    
        }
    
        if(value === '') {
            callback(new Error('必填项不能为空!'));
        } else if(!enoughLen) {
            callback(new Error('密码长度应在[8-16]位之间'))
        } else if (strength <= 5) {
            callback(new Error('当前密码强度较弱,存在安全风险!'));
        } else {
          callback();
        }
    }
    
    /**
     * 检查密码是否是常用弱口令
     * @param {string} password 待检测的密码
     * @returns {boolean} 是否是弱口令
     */
    function isWeakPassword(password) {
      // 常见弱口令列表(可根据需要扩展)
      const weakPasswords = [
        'password', '123456', '12345678', '123456789', '12345',
        '1234567', '1234567890', 'qwerty', 'abc123', 'admin',
        'welcome', 'monkey', 'letmein', 'password1', '123123',
        '111111', 'sunshine', 'iloveyou', 'admin123', '123qwe',
        'passw0rd', '1234', 'test', '123abc', '000000', 'abcdefgh'
      ];
    
      // 检查是否在弱口令列表中
      if (weakPasswords.includes(password.toLowerCase())) {
        return true;
      }
    
      // 检查是否是纯数字(6位以上)
      if (/^\d{6,}$/.test(password)) {
        return true;
      }
    
      // 检查是否是纯字母(6位以上)
      if (/^[a-zA-Z]{6,}$/.test(password)) {
        return true;
      }
    
      // 检查是否是连续数字或字母(如123456, abcdef)
      if (/(012345|123456|234567|345678|456789|567890|098765|987654|876543|765432|654321|543210|abcdef|bcdefg|cdefgh|defghi|efghij|fghijk|ghijkl|hijklm|ijklmn|jklmno|klmnop|lmnopq|mnopqr|nopqrs|opqrst|pqrstu|qrstuv|rstuvw|stuvwx|tuvwxy|uvwxyz|zyxwv|xwvut|wvuts|vutsr|utsrq|tsrqp|srqpo|rqpon|qponm|ponml|onmlk|nmlkj|mlkji|lkjih|kjihg|jihgf|ihgfe|hgfed|gfedc|fedcb|edcba)/i.test(password)) {
        return true;
      }
    
      // 检查是否是重复字符(如aaaaaa, 111111)
      if (/^([a-zA-Z0-9])\1{5,}$/.test(password)) {
        return true;
      }
    
      return false;
    }

方案一

    password: [{ required: true, validator: validatePassword, trigger: 'blur' }],
    
    export function validatePassword(rule, password, callback) {
        const WEAK_PASSWORDS = [
          'ABCabc123',
          'Admin123',
          '1qazXSW@',
          'aaaBBB111',
          // 可继续添加其他常见弱口令
        ];
        const SPECIAL_CHARS = "!@#$%^&*()_+-=[]{}|;:'\",.<>/?`~";
    
    
        if(password === '') {
            callback(new Error('必填项不能为空!'));
        }
    
        // 规则1:长度 8 ~ 16 位
        if (password.length < 8 || password.length > 16) {
            callback(new Error('密码长度必须为8位至16位!'));
        }
    
      // 规则3:不能是常用弱口令
      const lowerPassword = password.toLowerCase();
      if (WEAK_PASSWORDS.some(p => p.toLowerCase() === lowerPassword)) {
        callback(new Error('密码属于常用弱口令,请选择更复杂的密码!'));
      }
    
      // 检查字符类型
      let hasDigit = /\d/.test(password);
      let hasSpecial = new RegExp(`[${SPECIAL_CHARS.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}]`).test(password);
      let hasUpper = /[A-Z]/.test(password);
      let hasLower = /[a-z]/.test(password);
    
      let typeCount = [hasDigit, hasSpecial, hasUpper, hasLower].filter(Boolean).length;
    
      // 规则2:必须包含至少3种类型
      if (typeCount < 3) {
        callback(new Error('密码必须包含数字、特殊符号、大小写字母中的至少3项!'));
      }
    
      // 规则4:不能包含3个连续或相同的数字(正序/逆序)
      if (/(012|123|234|345|456|567|678|789|987|876|765|654|543|432|321|210)/.test(password)) {
        callback(new Error('密码不能包含3个连续或相同的数字(正序或逆序)!'));
      }
    
      // 规则5:不能包含3个连续或相同的字母(不区分大小写,正序/逆序)
      // 构建连续字母正序和逆序正则(a-z 和 z-a,不区分大小写)
      const lowerPwd = password.toLowerCase();
      // 正序连续三个字母如 abc, bcd, ..., xyz
      for (let i = 0; i <= 23; i++) {
        const a = String.fromCharCode(97 + i);
        const b = String.fromCharCode(97 + i + 1);
        const c = String.fromCharCode(97 + i + 2);
        const seq = a + b + c;
        if (lowerPwd.includes(seq)) {
          callback(new Error('密码不能包含3个连续的字母(正序或逆序)!'));
        }
      }
      // 逆序连续三个字母如 cba, bcd -> 这里只考虑逆序如 cba (即 z-a方向)
      for (let i = 0; i <= 23; i++) {
        const a = String.fromCharCode(97 + i + 2);
        const b = String.fromCharCode(97 + i + 1);
        const c = String.fromCharCode(97 + i);
        const seq = a + b + c;
        if (lowerPwd.includes(seq)) {
          callback(new Error('密码不能包含3个连续的字母(正序或逆序)!'));
        }
      }
    
      // 检查3个相同的字母(不区分大小写)
      const sameLetterRegex = /(.)\1{2}/; // 任意字符连续出现3次
      if (sameLetterRegex.test(lowerPwd)) {
        callback(new Error('密码不能包含3个相同的字母(不区分大小写)!'));
      }
    
      // 所有规则通过
      callback();
    }
posted on 2025-11-11 19:55  羽丫头不乖  阅读(0)  评论(0)    收藏  举报