feat: 密码强度校验增强,要求大写+小写+数字
- validatePassword 从"字母+数字"升级为"大写字母+小写字母+数字" - 拆分 pwLetter 为 pwLower([a-z]) 和 pwUpper([A-Z]) - 更新 ErrWeakPassword 错误提示 - 同步更新注册页和修改密码页的前端校验及提示文案
This commit is contained in:
@ -14,7 +14,7 @@ var (
|
||||
ErrUserDeleted = errors.New("该账号正在注销中,登录即撤销注销")
|
||||
// 统一返回,避免泄露用户存在性、软删除状态等内部信息
|
||||
ErrUserLocked = errors.New("邮箱或密码错误")
|
||||
ErrWeakPassword = errors.New("密码需至少 8 位,且包含字母和数字")
|
||||
ErrWeakPassword = errors.New("密码需至少 8 位,且包含大写字母、小写字母和数字")
|
||||
ErrTokenExpired = errors.New("登录已过期,请重新登录")
|
||||
ErrTokenInvalid = errors.New("无效的认证凭据")
|
||||
ErrTokenRevoked = errors.New("登录凭证已失效,请重新登录")
|
||||
|
||||
@ -11,7 +11,8 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var pwLetter = regexp.MustCompile(`[a-zA-Z]`)
|
||||
var pwLower = regexp.MustCompile(`[a-z]`)
|
||||
var pwUpper = regexp.MustCompile(`[A-Z]`)
|
||||
var pwDigit = regexp.MustCompile(`\d`)
|
||||
|
||||
// dummyHash 防时序攻击:当用户不存在时,仍对虚拟哈希执行完整的 bcrypt 比对
|
||||
@ -25,9 +26,9 @@ func init() {
|
||||
dummyHash = hash
|
||||
}
|
||||
|
||||
// validatePassword 密码强度:至少 8 位 + 包含字母 + 包含数字
|
||||
// validatePassword 密码强度:至少 8 位 + 包含大写字母 + 包含小写字母 + 包含数字
|
||||
func validatePassword(pw string) error {
|
||||
if len(pw) < 8 || !pwLetter.MatchString(pw) || !pwDigit.MatchString(pw) {
|
||||
if len(pw) < 8 || !pwLower.MatchString(pw) || !pwUpper.MatchString(pw) || !pwDigit.MatchString(pw) {
|
||||
return common.ErrWeakPassword
|
||||
}
|
||||
return nil
|
||||
|
||||
@ -23,8 +23,8 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">密码</label>
|
||||
<input type="password" id="password" placeholder="至少 8 位,包含字母与数字" required minlength="8">
|
||||
<span class="form-error" id="passwordError">密码至少 8 位,需包含字母与数字</span>
|
||||
<input type="password" id="password" placeholder="至少 8 位,包含大小写字母与数字" required minlength="8">
|
||||
<span class="form-error" id="passwordError">密码至少 8 位,需包含大小写字母与数字</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="confirmPassword">确认密码</label>
|
||||
|
||||
@ -274,7 +274,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="newPassword">新密码</label>
|
||||
<input type="password" id="newPassword" class="settings-text-input" placeholder="至少 8 位,包含字母和数字" autocomplete="new-password">
|
||||
<input type="password" id="newPassword" class="settings-text-input" placeholder="至少 8 位,包含大小写字母和数字" autocomplete="new-password">
|
||||
</div>
|
||||
<div class="settings-card-footer">
|
||||
<button id="changePwdBtn" class="settings-save-btn">修改密码</button>
|
||||
@ -736,8 +736,8 @@
|
||||
showSettingsToast('请输入当前密码', true);
|
||||
return;
|
||||
}
|
||||
if (!newPwd.value || !/[a-zA-Z]/.test(newPwd.value) || !/\d/.test(newPwd.value) || newPwd.value.length < 8) {
|
||||
showSettingsToast('新密码至少 8 位,包含字母和数字', true);
|
||||
if (!newPwd.value || !/[a-z]/.test(newPwd.value) || !/[A-Z]/.test(newPwd.value) || !/\d/.test(newPwd.value) || newPwd.value.length < 8) {
|
||||
showSettingsToast('新密码至少 8 位,包含大小写字母和数字', true);
|
||||
return;
|
||||
}
|
||||
changePwdBtn.disabled = true;
|
||||
|
||||
@ -165,7 +165,7 @@
|
||||
var password = passwordInput.value;
|
||||
var confirm = confirmPasswordInput.value;
|
||||
var emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
||||
var passwordValid = password.length >= 8 && /[a-zA-Z]/.test(password) && /\d/.test(password);
|
||||
var passwordValid = password.length >= 8 && /[a-z]/.test(password) && /[A-Z]/.test(password) && /\d/.test(password);
|
||||
var confirmValid = passwordValid && confirm === password;
|
||||
submitBtn.disabled = !(emailValid && passwordValid && confirmValid);
|
||||
}
|
||||
@ -184,7 +184,7 @@
|
||||
|
||||
passwordInput.addEventListener('input', function () {
|
||||
var v = passwordInput.value;
|
||||
if (v && (v.length < 8 || !/[a-zA-Z]/.test(v) || !/\d/.test(v))) {
|
||||
if (v && (v.length < 8 || !/[a-z]/.test(v) || !/[A-Z]/.test(v) || !/\d/.test(v))) {
|
||||
passwordInput.classList.add('error');
|
||||
passwordError.style.display = 'block';
|
||||
} else {
|
||||
@ -228,7 +228,7 @@
|
||||
emailError.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
if (password.length < 8 || !/[a-zA-Z]/.test(password) || !/\d/.test(password)) {
|
||||
if (password.length < 8 || !/[a-z]/.test(password) || !/[A-Z]/.test(password) || !/\d/.test(password)) {
|
||||
passwordInput.classList.add('error');
|
||||
passwordError.style.display = 'block';
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user