【发布时间】:2016-02-15 09:48:58
【问题描述】:
我的网络应用程序将在注册表单上生成密码。 但用户可以随意更改密码。
当用户输入密码时,必须遵守我们的密码政策。
我们的密码政策是:
- 密码长度必须大于等于8
- 密码必须包含一个或多个大写字符
- 密码必须包含一个或多个小写字符
- 密码必须包含一个或多个数值
- 密码必须包含一个或多个特殊字符
正则表达式是 (?=^.{8,}$)(?=.\d)(?=.[.!@#$%^&]+) (?![.\n])(?=.[AZ])(?=.[az]).$
这是我生成密码的 C# 代码:
Regex passPattern = new Regex("(?=^.{8,}$)(?=.*\\d)(?=.*[!@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$");
var password = System.Web.Security.Membership.GeneratePassword(10,2);
while (true)
{
if (!passPattern.IsMatch(password))
{
password = System.Web.Security.Membership.GeneratePassword(10, 2);
}
else
{
break;
}
}
它将循环并不断生成密码,直到匹配为止。
在表单上,我还使用 Jquery 验证密码策略。这里的代码 sn -p :
<script type="text/javascript">
$('#newPassword').keyup(function(e) {
var strongRegex = new RegExp("(?=^.{8,}$)(?=.*\d)(?=.*[!@@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$", "g");
var enoughRegex = new RegExp("(?=.{8,}).*", "g");
if (false == enoughRegex.test($(this).val())) {
$('#passstrength').html('More Characters');
}
else if (strongRegex.test($(this).val())== true) {
$('#passstrength').html('Meet Our Password Policy!');
}
else {
$('#passstrength').html('Please insert strength password!');
}
return true;
});
所以结果:
- A%rI_2{l#Y = 不匹配
- P@ssw0rd.123 = 匹配
- 2@C*DjDQdJ = 匹配
- ex@#XcINQ0 = 不匹配
如您所见,并非所有密码都匹配。所有这些值都已在 regex101.com 和 regexpal.com 进行了测试,所有结果都匹配。
那么如何解决这个问题呢?
p/s:我在我的页面中使用 razor 引擎,所以你可以在 jquery 的正则表达式上看到双“@”。
【问题讨论】:
-
您至少犯了 2 个基本错误:1) 永远不要将
/g与RegExp.test()一起使用 2) 在已知模式时不要使用构造函数表示法,使用文字正则表达式表示法(或你必须双反斜杠)(即使用var strongRegex = /^(?=.{8,}$)(?=.*\d)(?=.*[!@@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/;)。而不是var enoughRegex = new RegExp("(?=.{8,}).*", "g");,你真的可以只检查密码长度。顺便说一句,为什么要使用(?![.\n])?似乎没有要求不以点或换行开头。 -
真的需要正则表达式吗?没有它,实现和阅读会容易得多(以及更明智的错误为什么密码无效)
-
为什么您不只是使用应用于模型属性的
[RegularExpression]属性,以便在没有任何此代码的情况下获得开箱即用的客户端和服务器端验证? -
@StephenMuecke:请注意,服务器端和客户端的验证是不同的。这也是一个好问题,顺便说一句。
标签: c# jquery regex asp.net-mvc