基本概念理解
通过添加自定义限制来修改应用的强密码规则。
虽然自动填充密码生成的强密码安全性已经很好了,但我们的应用可能需要自定义的限制才能与其他技术保持兼容。
遵循UITextInputTraits协议UIKit控件(UITextField、UITextView),通过设置
passwordRules属性或网页中HTML input元素中的passwordrules属性来自定义自动生成的密码的密码规则。
这两个属性的值必须遵循以下形式的相同限制:
required: (<identifier> | <character-class>), ..., (<identifier> | <character-class>); allowed: (<identifier> | <character-class>), ..., (<identifier> | <character-class>); max-consecutive: <non-negative-integer>
使用关键字组合来指定规则:
- required&allowed关键字:如果所有密码都必须遵循某个限制条件,则使用required关键字; 如果限制条件是指定允许字符的子集,则允许allowed关键字。 如果不包含allowed关键字,则允许使用所有必需字符。 如果包含这两个属性,则允许使用所有允许和必需的字符。 如果两者都未指定,则允许所有ASCII可打印字符
- 限制条件:可以使用大写(A-Z),小写(a-z),数字(0-9),特殊字符(-〜!@#$%^&* _+=`|(){}[:;“'<>,.?]和空格),ascii-printable(所有ASCII可打印字符)或unicode(所有unicode字符)
- 最大长度关键字:使用max-consecutive指定密码中连续字符的最大长度。 如果规则中有多个最大连续属性,则将应用属性的最小值。 如果没有此属性,密码可以是任何长度。
- 自定义字符类:<character-class>是自定义字符类。 此属性包含由方括号括起的ASCII字符列表。 例如,[abc]仅允许字符“a”,“b”和“c”。
- Non-negative类:<非负整数>是有效的非负整数。 此属性用于指定max-consecutive属性,因为最大长度不能为负。
应用默认密码规则:没有任何自定义的密码规则。 它允许所有ASCII可打印字符,写为allowed:ascii-printable。
可以组合这些关键字来形成规则。 原则上会忽略重复的属性值,空字符类和没有值的属性。 如果使用密码规则,请不要指定pattern属性。 如果您有两个密码字段(一个用于密码,一个用于确认),则当用户输入新密码时,您无需为这两个字段指定密码规则。
Warning
您对密码的限制越多,被攻破的可能性就越高。 最难猜测的密码规则就是allowed:unicode
。
假如指定的密码长度不能小于12,允许的字符必须至少包含以下两个类:ASCII大写字母,ASCII小写字母和数字。 如果在为UITextField、UITextView设置了密码规则之后,但是密码限制条件不符合这些准则,则用户代理将忽略这些属性。
构建密码规则
例如,假设您要求密码至少包含八个字符,这些字符由大写和小写字母以及至少一个数字和最多两个连续字符组成
let newPasswordTextField = UITextField()
newPasswordTextField.passwordRules = UITextInputPasswordRules(descriptor: "required: upper; required: lower; required: digit; max-consecutive: 2; minlength: 8;")
在上面的前提下变更一下对于数字部分的要求:至少一个数字或一个特殊字符,两者有其一即可
let newPasswordTextField = UITextField()
newPasswordTextField.passwordRules = UITextInputPasswordRules(descriptor: "required: upper; required: lower; required: digit, [-().&@?'#,/"+]; max-consecutive: 2; minlength: 8;")
至少需要一组特殊字符( - ()。&@?'#,/“+):
let newPasswordTextField = UITextField()
newPasswordTextField.passwordRules = UITextInputPasswordRules(descriptor: "required: upper; required: lower; required: digit; required: [-().&@?'#,/"+]; max-consecutive: 2; minlength: 8;")
或者,要选择允许一个特殊字符
let newPasswordTextField = UITextField()
newPasswordTextField.passwordRules = UITextInputPasswordRules(descriptor: "required: upper; required: lower; required: digit; allowed: [-().&@?'#,/"+]; max-consecutive: 2; minlength: 8;")
另外一个例子是,要允许密码包含任意组合的字母,数字和特殊字符
let newPasswordTextField = UITextField()
newPasswordTextField.passwordRules = UITextInputPasswordRules(descriptor: "allowed: upper, lower, digit, [-().&@?’#,/"+]; minlength: 8;")
指定多个字符类相当于指定一个字符类,该字符类表示所有字符类中字符的并集。
这种等效性的例外是必需的。 密码必须在每个指定的必需属性中包含至少一个字符。 例如:
allowed: upper; allowed: lower <=> allowed: upper, lower
required: upper; required: lower <=> required: upper; required: lower
完整事例
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(100, 30, 200, 50)];
field.textColor = [UIColor blackColor];
field.backgroundColor = [UIColor yellowColor];
field.secureTextEntry = YES;
if (@available(iOS 12.0, *)) {
field.textContentType = UITextContentTypeNewPassword;
UITextInputPasswordRules *passwordRules = [UITextInputPasswordRules passwordRulesWithDescriptor:@"required: upper; required: lower; required: digit; max-consecutive: 2; minlength: 8;"];
field.passwordRules = passwordRules;
} else {
// Fallback on earlier versions
field.textContentType = UITextContentTypePassword;
}
[self.view addSubview:field];
passwordRules属性用于传达服务密码的要求,以确保iOS可以为用户生成兼容的密码。 它仅在secureTextEntry为YES时有效。 如果iOS生成的密码已与您的服务兼容,则无需使用此属性。 您可以在“密码规则”文档指南中了解有关这些规则的用途和语法的更多信息。