当前位置: 首页 > 知识库问答 >
问题:

Angular 5中的自定义密码验证

江向阳
2023-03-14

我正在尝试将自定义密码验证添加到密码字段。密码必须至少包含 8 个字符,并且至少满足以下两个条件,但不必满足所有四个条件:

  • 具有数字
  • 具有小写字母
  • 具有大写字母
  • 具有特殊字符

我已经完成了部分验证工作,但遇到了一个问题,如果密码长度为8个字符,但不满足以上至少两个条件,错误消息将不会显示。只有当密码少于8个字符时,才会显示有关字符的错误。

我在SO中进行了搜索,但没有成功实现类似问题的答案。我怀疑我遇到的问题与我的自定义验证函数没有与ngModel中的密码相关联有关。

问题:当密码长度为8个字符但不符合上述字符要求时,如何使错误消息显示在表单字段上?

下面是关联的代码。

来自user-form.html:

 <mat-form-field *ngIf="newPassword" fxFlex="100%">
  <input matInput #password="ngModel" placeholder="Password" type="password" autocomplete="password"
         [(ngModel)]="model.password" name="password" minlength="8" (keyup)="validatePassword(model.password)" required>
  <mat-error *ngIf="invalidPassword">
    Password must contain at least two of the following: numbers, lowercase letters, uppercase letters, or special characters.
  </mat-error>
  <mat-error *ngIf="password.invalid && (password.dirty || password.touched)">
    <div *ngIf="password.errors.required">
      Password is required
    </div>
    <div *ngIf="password.errors.minlength">
      Password must be at least 8 characters
    </div>
  </mat-error>
</mat-form-field>

从user-form.component.ts:

export class UserFormComponent implements OnInit {


  @Input()
  user: User;

  public model: any;
  public invalidPassword: boolean;


  constructor() {}

  ngOnInit() {
    this.model = this.user;
  }


  passwordFails(checks: boolean[]): boolean {
     let counter = 0;
    for (let i = 0; i < checks.length; i++) {
      if (checks[i]) {
        counter += 1;
      }
    }
    return counter < 2;
 }


  validatePassword(password: string) {
    let hasLower = false;
    let hasUpper = false;
    let hasNum = false;
    let hasSpecial = false;

    const lowercaseRegex = new RegExp("(?=.*[a-z])");// has at least one lower case letter
    if (lowercaseRegex.test(password)) {
      hasLower = true;
    }

    const uppercaseRegex = new RegExp("(?=.*[A-Z])"); //has at least one upper case letter
    if (uppercaseRegex.test(password)) {
      hasUpper = true;
    }

    const numRegex = new RegExp("(?=.*\\d)"); // has at least one number
    if (numRegex.test(password)) {
      hasNum = true;
    }

    const specialcharRegex = new RegExp("[!@#$%^&*(),.?\":{}|<>]");
    if (specialcharRegex.test(password)) {
      hasSpecial = true;
    }

    this.invalidPassword = this.passwordFails([hasLower, hasUpper, hasNum, hasSpecial]);
  }
}

共有3个答案

马阳曦
2023-03-14

您正在将布尔值传递给函数

this.invalidPassword = this.passwordFails([hasLower, hasUpper, hasNum, hasSpecial]);

将您的函数更改如下,如果密码不符合其中一个条件,将返回true。

passwordFails(checks: boolean[]): boolean {
   return checks.filter((x)=> typeof x === 'boolean' && x === true).length > 2
}

在dom中,您可以添加另一个条件来检查无效的密码

 <mat-form-field *ngIf="newPassword" fxFlex="100%">
  <input matInput #password="ngModel" placeholder="Password" type="password" autocomplete="password"
         [(ngModel)]="model.password" name="password" minlength="8" (keyup)="validatePassword(model.password)" required>
  <mat-error *ngIf="invalidPassword">
    Password must contain at least two of the following: numbers, lowercase letters, uppercase letters, or special characters.
  </mat-error>
  <mat-error *ngIf="password.invalid && (password.dirty || password.touched)">
    <div *ngIf="password.errors.required">
      Password is required
    </div>
    <div *ngIf="password.errors.minlength">
      Password must be at least 8 characters
    </div>
    <div *ngIf="!invalidPassword">
      Password must meet the following criteria.
    </div>
  </mat-error>
</mat-form-field>
韦熙云
2023-03-14

Stackblitz演示

组件.html

<div class="error-text" *ngIf="myForms.get('password').hasError('passwordStrength')">
    {{myForms.get('password').errors['passwordStrength']}}
</div>

Component.ts

this.myForms = fb.group({
      password: [null, Validators.compose([
        Validators.required, Validators.minLength(8), PasswordStrengthValidator])]
});

密码强度.验证器. ts

import { AbstractControl, ValidationErrors } from "@angular/forms"

export const PasswordStrengthValidator = function (control: AbstractControl): ValidationErrors | null {


let value: string = control.value || '';
  let msg="";
  if (!value) {
    return null
  }

  let upperCaseCharacters = /[A-Z]+/g;
  let lowerCaseCharacters = /[a-z]+/g;
  let numberCharacters = /[0-9]+/g;
  let specialCharacters = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]+/;
  if (upperCaseCharacters.test(value) === false || lowerCaseCharacters.test(value) === false || numberCharacters.test(value) === false || specialCharacters.test(value) === false) {
return {
  passwordStrength: 'Password must contain at least two of the following: numbers, lowercase letters, uppercase letters, or special characters.'
}

}

}
厉高逸
2023-03-14

我进一步玩了一下,看看我是否可以弄清楚如何在Angular中使用验证器。我终于能够通过这些更新做到这一点:

创建password-validator.directive.ts:

import { Directive, forwardRef, Attribute} from "@angular/core";
import { Validator, AbstractControl, NG_VALIDATORS} from "@angular/forms";

@Directive({
  selector: '[validatePassword]',
  providers: [
    { provide: NG_VALIDATORS, useExisting: forwardRef(() => PasswordValidator), multi: true}
  ]
})

export class PasswordValidator implements Validator {
  constructor (
    @Attribute('validatePassword')
    public invalidPassword: boolean
  ) {}

  validate(ctrl: AbstractControl): {[key: string]: any} {
    let password = ctrl.value;

    let hasLower = false;
    let hasUpper = false;
    let hasNum = false;
    let hasSpecial = false;

    const lowercaseRegex = new RegExp("(?=.*[a-z])");// has at least one lower case letter
    if (lowercaseRegex.test(password)) {
      hasLower = true;
    }

    const uppercaseRegex = new RegExp("(?=.*[A-Z])"); //has at least one upper case letter
    if (uppercaseRegex.test(password)) {
      hasUpper = true;
    }

    const numRegex = new RegExp("(?=.*\\d)"); // has at least one number
    if (numRegex.test(password)) {
      hasNum = true;
    }

    const specialcharRegex = new RegExp("[!@#$%^&*(),.?\":{}|<>]");
    if (specialcharRegex.test(password)) {
      hasSpecial = true;
    }

    let counter = 0;
    let checks = [hasLower, hasUpper, hasNum, hasSpecial];
    for (let i = 0; i < checks.length; i++) {
      if (checks[i]) {
        counter += 1;
      }
    }

    if (counter < 2) {
      return { invalidPassword: true }
    } else {
      return null;
    }



  }

}

user-form.component.html更新:

<mat-form-field *ngIf="newPassword" fxFlex="100%">
  <input matInput #password="ngModel" placeholder="Password" type="password" autocomplete="password"
         [(ngModel)]="model.password" name="password" minlength="8" validatePassword="password" required>
  <mat-error *ngIf="password.invalid && (password.dirty || password.touched)">
    <div *ngIf="password.errors.invalidPassword">
      Password must have two of the four: lowercase letters, uppercase letters, numbers, and special characters
    </div>
    <div *ngIf="password.errors.required">
      Password is required
    </div>
    <div *ngIf="password.errors.minlength">
      Password must be at least 8 characters
    </div>
  </mat-error>
</mat-form-field>

user-form.module.ts更新:

import {PasswordValidator} from "../password-validator.directive"; //imported to modules

@NgModule({
  imports: [
    //some modules
  ],
  declarations: [
    // some modules
    PasswordValidator // added this to declarations
  ],
  exports: [
    // stuff
  ],
  providers: [
    //stuff
  ]
})
export class UserFormModule { }
 类似资料:
  • 我正在尝试实现AES自定义密码加密,并希望了解下面的代码。 我不太理解为什么需要指定密钥大小256“pbekeyspec(password,salt,65536,256)”,而我已经使用了“pbkdf2withHMACSHA256”,它应该生成256位的SecretKey。 并且在使用我的密码+salt生成密钥之后,为什么我需要将它与SecretKeySpec作为AES算法关联起来。

  • 所以在我的安装中似乎缺少了几个类。无论如何,我尝试在我的po.xml文件中包含所有需要的依赖项。 我的pom.xml文件: 我的QueryAndenCodeDatabaseAuthenticationHandler.java文件(尚未修改!): 最后是我的AbstractJDBCUserNamePasswordAuthenticationHandler.java(也未修改):

  • 表单验证发生在数据验证之后。如果你需要定制化这个过程,有几个不同的地方可以修改,每个地方的目的不一样。表单处理过程中要运行三种类别的验证方法。它们通常在你调用表单的is_valid() 方法时执行。还有其它方法可以触发验证过程(访问errors 属性或直接调用full_clean() ),但是通用情况下不需要。 一般情况下,如果处理的数据有问题,每个类别的验证方法都会引发ValidationErr

  • 本文向大家介绍Android自定义View实现验证码,包括了Android自定义View实现验证码的使用技巧和注意事项,需要的朋友参考一下 本文章是基于鸿洋的Android 自定义View (一) 的一些扩展,以及对Android自定义View构造函数详解里面内容的一些转载。 首先我们定义一个declare-styleable标签declare-styleable标签的作用是给自定义控件添加自定义

  • 我想用bcrypt和Spring security哈希和salt用户密码。 下面是我如何用他们自己的salt创建新用户: 下面是spring配置: 在此配置中,我指示必须使用; 有没有办法使用我的?或 哪个可靠的算法允许我的? 多谢了。

  • 我使用laravel 5.6,并成功地将视图作为电子邮件发送。 我使用以下代码: 我唯一的问题是密码重置。我知道我可以自定义一点模板,但是如何覆盖默认的电子邮件模板并发送我自己的视图? 我尝试写我自己的ResetPassword通知: 但我只能翻译电子邮件。我想要的是根据我自己的模板发送我自己的视图。 可能吗? 谢谢你的帮助。