密码错误尝试限制 go语言实现
// 错误密码尝试限制
type UserAccount struct {
Attempts int // 登录尝试次数
LastTry time.Time
}
// 使用map和互斥锁来存储用户登录信息
var userAttempts = make(map[string]UserAccount)
var mu sync.Mutex
// 允许的最大尝试次数
const maxAttempts = 5
// 等待时间(分钟)
const waitTimeMinutes = 15
// updatePasswordAttempt 更新指定用户的密码错误次数
func updatePasswordAttempt(username string) {
mu.Lock()
defer mu.Unlock()
account, exists := userAttempts[username]
if !exists {
account = UserAccount{
Attempts: 1, // 如果是新用户,则首次尝试算作一次
LastTry: time.Now(),
}
} else {
account.Attempts++
account.LastTry = time.Now()
}
userAttempts[username] = account
}
// shouldWait 检查用户是否因为密码错误次数过多而需要等待
func shouldWait(username string) (bool, time.Duration) {
mu.Lock()
defer mu.Unlock()
account, exists := userAttempts[username]
if !exists || account.Attempts < maxAttempts {
// 不存在该用户或尝试次数未超过限制,不需要等待
return false, 0
}
// 计算还需要等待多久
waitDuration := time.Duration(waitTimeMinutes)*time.Minute - time.Since(account.LastTry)
if waitDuration <= 0 {
// 如果已经超过等待时间,重置尝试次数
account.Attempts = 0
userAttempts[username] = account
return false, 0
}
// 返回需要等待的时长
return true, waitDuration
}
// end 校验密码 避免撞库