【问题标题】:How to validate password strength with Angular 5 Validator Pattern如何使用 Angular 5 验证器模式验证密码强度
【发布时间】:2018-06-29 05:59:48
【问题描述】:

我需要验证密码输入表单域的强度。要求是:

  • 至少一个小写字符
  • 至少一个大写字符
  • 至少一个数字
    (不分先后)

到目前为止我搜索和尝试的内容如下,结果不一致。

似乎验证了正则表达式验证的顺序。
我需要的是检查是否存在至少一种 char “类型”。

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
    selector: 'signup',
    templateUrl: './signup.component.html',
    styleUrls: ['./signup.component.scss']
})
export class SignupComponent {

    form: FormGroup;

    constructor() {
        this.init();
    }

    init() {
        this.form = this.fb.group({
            name: ['', [Validators.required]],
            email: ['', [Validators.required, Validators.email],
            password: ['', [
                Validators.required, 
                Validators.pattern('((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,30})')
            ]]
        }); 
    }
}

【问题讨论】:

  • \ 必须加倍。 (?=.*\d) -> (?=.*\\d)
  • 您可能会受益于Reference - Password Validation
  • @WiktorStribiżew 您应该将此作为答案发布,以便 OP 可以选择它作为此问题的答案
  • @Sytham Done.
  • 如果您有时间,请考虑接受最适合您的答案。

标签: regex angular validation


【解决方案1】:
Validators.pattern(/^(?=\D*\d)(?=[^a-z]*[a-z])(?=.*[$@$!%*?&])(?=[^A-Z]*[A-Z]).{8,30}$/)

【讨论】:

    【解决方案2】:

    以下解决方案认为密码要求的参数可能是动态的

    该方法动态生成模式字符串

      passRequirement = {
        passwordMinLowerCase: 1,
        passwordMinNumber: 1,
        passwordMinSymbol: 2,
        passwordMinUpperCase: 1,
        passwordMinCharacters: 8
      };
      pattern = [
        `(?=([^a-z]*[a-z])\{${this.passRequirement.passwordMinLowerCase},\})`,
        `(?=([^A-Z]*[A-Z])\{${this.passRequirement.passwordMinUpperCase},\})`,
        `(?=([^0-9]*[0-9])\{${this.passRequirement.passwordMinNumber},\})`,
        `(?=(\.\*[\$\@\$\!\%\*\?\&])\{${this.passRequirement.passwordMinSymbol},\})`,
        `[A-Za-z\\d\$\@\$\!\%\*\?\&\.]{${
          this.passRequirement.passwordMinCharacters
        },}`
      ]
        .map(item => item.toString())
        .join("");
      resetPwdForm = this.fb.group({
        newpwdctrlname: ['Passwod1@@5', [Validators.required, Validators.pattern(this.pattern)]],
        shownewpwdctrlname: ['', []],
        rptpwdctrlname: ['', [Validators.required]]
      });
      constructor (private fb: FormBuilder) {}
    

    看到这个demo on stackblitz

    【讨论】:

    • 您好,非常感谢您的贡献,您将如何将以下内容添加到验证中?不允许超过两个数字的序列,例如:123、321 不允许使用 qwerty 类型的字符串,例如:asdf 非常感谢您。
    • @FernandoArbelo 请创建一个新问题,您可以在评论中添加链接我可以看看
    • 非常感谢。我认为您的解决方案更完整,因为您可以参数化密码强度验证。也因为你提供了工作演示。竖起大拇指!
    【解决方案3】:

    为了彻底起见,这里是一个真正有效并包含所有符号的验证器正则表达式:

    必须有数字,必须有小写字母,必须有大写字母,并且必须有标准 qwerty 键盘上可能出现的任何其他符号之一。

    确保在 typescript 或 javascript 中每个斜线都正确加倍。

    Validators.pattern('(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[`~!@#$%^&\\\\*\\\\(\\\\)\\\\-_=\\\\+\\\\{\\\\}\\\\[\\\\]|\\\\\\\\:;"\\'<>,\\\\.?\\\\/]).{8,}')
    

    【讨论】:

      【解决方案4】:

      如果您查看Validator.js,您会注意到您可以将字符串或正则表达式文字都传递给Validators.pattern

      正则表达式作为字符串文字传递

      • 整个字符串必须与模式匹配(即模式锚定在两侧)
      • 反斜杠可以形成字符串转义序列,您必须使用双反斜杠来定义用于定义正则表达式转义的文字反斜杠。因此,要定义数字匹配模式,请使用'\\d',要定义空格模式,请使用'\\s',要定义反斜杠,请使用'\\\\'

      正则表达式作为正则表达式文字传递

      • 正则表达式不会自动要求完整的字符串匹配。
      • 使用单个反斜杠定义正则表达式转义(例如/\s+/

      所以,你可以使用两者之一:

      this.form = this.fb.group({
          name: ['', [Validators.required]],
          email: ['', [Validators.required, Validators.email],
          password: ['', [
              Validators.required, 
              Validators.pattern('(?=\\D*\\d)(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z]).{8,30}')
       ]]
      });
      

      或者

      this.form = this.fb.group({
          name: ['', [Validators.required]],
          email: ['', [Validators.required, Validators.email],
          password: ['', [
              Validators.required, 
              Validators.pattern(/^(?=\D*\d)(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z]).{8,30}$/)
       ]]
      });
      

      正则表达式详细信息

      请注意,我建议的模式更改仅与the principle of contrast 相关:

      • ^ - 字符串开头(字符串正则表达式模式中隐含)
      • (?=\D*\d) - 必须有 1 个数字
      • (?=[^a-z]*[a-z]) - 必须有 1 个小写 ASCII 字母
      • (?=[^A-Z]*[A-Z]) - 必须有 1 个大写 ASCII 字母
      • .{8,30} - 除换行符以外的任何 8 到 30 个字符
      • $ - 字符串结尾(隐含在字符串正则表达式模式中)。

      【讨论】:

        【解决方案5】:

        我使用 Angular 的内置模式验证器对此进行了尝试,并能够提出以下检查:

        • 长度至少为 8 个字符
        • 小写字母
        • 大写字母
        • 数字
        • 特殊字符

          password: [
            '',
            [
              Validators.required,
              Validators.pattern('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&].{8,}')
             ]
          ]
          

        我要补充一点,我绝不是正则表达式专家。对于与 OP 密切相关的案例,这只是对我有用的方法。也许它会帮助别人。 Mozilla 的文档在解决这一问题方面提供了很大帮助,特别是 Writing a regular expression pattern 部分。

        【讨论】:

        • 不错的解决方案。虽然有两句话。由于量词前有一个点,您的正则表达式需要 9 个字符长度。它只允许使用正则表达式中列出的特殊字符。这是我的更新版本,它允许任何特殊字符,但至少需要正则表达式 (?=.*[az])(?=.*[AZ])(?=.*[0-9])(?= .*[!@#$%^&]).{8,}
        • 我同意最后一个点可以去掉?
        • 这不是 OP 要求的,他要求: - 至少一个小写字符 - 至少一个大写字符 - 至少一个数字 这是 OP 要求的有效模式:Validators.pattern ('((?=.*\\d)(?=.*[az])(?=.*[AZ]).{8,30})')
        • 您的表达式是唯一适用于我的 ionic 4 应用程序的表达式。非常感谢
        【解决方案6】:

        我无法正确使用验证器模式,所以我制作了一个自定义验证器,并使用三个简单的正则表达式验证密码字段字符串。
        无论如何,我期待正确使用 Angular验证器模式。

        自定义验证器

        // password.validator.ts
        
        import { FormControl } from '@angular/forms';
        
        export interface ValidationResult {
            [key: string]: boolean;
        }
        
        export class PasswordValidator {
        
            public static strong(control: FormControl): ValidationResult {
                let hasNumber = /\d/.test(control.value);
                let hasUpper = /[A-Z]/.test(control.value);
                let hasLower = /[a-z]/.test(control.value);
                // console.log('Num, Upp, Low', hasNumber, hasUpper, hasLower);
                const valid = hasNumber && hasUpper && hasLower;
                if (!valid) {
                    // return what´s not valid
                    return { strong: true };
                }
                return null;
            }
        }
        

        用我的自定义验证器替换验证器模式

        // signup.component.ts
        
        import { Component } from '@angular/core';
        import { FormBuilder, FormGroup, Validators } from '@angular/forms';
        import { PasswordValidator } from 'validators/password.validator';
        
        @Component({
            selector: 'signup',
            templateUrl: './signup.component.html',
            styleUrls: ['./signup.component.scss']
        })
        export class SignupComponent {
        
            form: FormGroup;
        
            constructor() {
                this.init();
            }
        
            init() {
                this.form = this.fb.group({
                    name: ['', [Validators.required]],
                    email: ['', [Validators.required, Validators.email],
                    password: ['', [
                        Validators.required, 
                        PasswordValidator.strong
                    ]]
                }); 
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2014-05-23
          • 2010-09-16
          • 2019-03-31
          • 2016-12-17
          • 2020-05-17
          • 1970-01-01
          • 2013-03-18
          相关资源
          最近更新 更多