密码强度校验须拆解为长度、大小写字母、数字、特殊字符五项独立逻辑,前后端双重验证并提供结构化错误反馈,禁用复杂正则以防ReDoS。

密码强度的复杂规则校验不能只靠一条正则“一锤定音”,必须拆解为可验证、可反馈、可维护的分项逻辑,同时坚持前后端双重校验。
明确并拆解核心规则项
先定义清楚哪些是硬性要求,再逐项检查,避免用复杂前瞻断言(如 (?=.*[a-z]))带来兼容性或 ReDoS 风险:
- 长度 ≥ 8 且 ≤ 64(用
strlen()或password.length直接判断) - 至少含一个小写字母(
/[a-z]/.test(pwd)或遍历char.isLower()) - 至少含一个大写字母(
/[A-Z]/.test(pwd)) - 至少含一个数字(
/\d/.test(pwd),注意不匹配全角数字) - 至少含一个白名单内的特殊字符(如
!@#$%^&*()_+-=[]{}|;':",.?,禁用宽泛的\W)
拒绝单正则兜底,优先分步验证
单条含多个 (?=...) 的正则在 PHP/PCRE 中易引发回溯爆炸(ReDoS),在 Safari 或旧版 Edge 中可能失效。更可靠的做法是独立调用多次基础匹配:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- PHP 示例:用
strlen()+ 多个preg_match()汇总错误数组 - JavaScript 示例:用
some()遍历字符,分别标记hasLower、hasUpper等布尔值 - Java 示例:遍历
char数组,用布尔变量记录四类字符是否出现过
提供精准、友好的失败反馈
用户需要知道“缺什么”,而不是“不合法”。不要返回笼统的“密码强度不足”:
- 收集未达标项,拼接提示:“需包含大写字母和特殊字符”
- 前端实时显示强度等级(弱/中/强)时,按满足项数计分:1–2 项为弱,3 项为中,4–5 项为强
- 后端返回结构化错误(如
{"field": "password", "issues": ["missing_upper", "missing_special"]}),便于前端映射友好文案
必须服务端二次校验,且与前端逻辑严格对齐
前端校验可被绕过,服务端才是最终防线。ThinkPHP 应用验证器类,Java 用自定义注解或工具方法,PHP 常规表单用 validate 规则链:
- ThinkPHP 6+:在验证器中写
['password' => 'require|length:8,64|regex:/[a-z]/|regex:/[A-Z]/|regex:/\d/|regex:/[!@#\$%]/'],或重写check()方法做细粒度控制 - Java:避免在 setter 中直接哈希,应在业务层调用校验服务后再执行
passwordEncoder.encode() - 所有环境都应提前
trim()去首尾空格,防止用户无意输入空格导致误判

















