| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- package services
- import (
- "fmt"
- "sync"
- "time"
- )
- var (
- // 登录尝试记录
- loginAttempts = struct {
- sync.RWMutex
- m map[string]AttemptInfo
- }{m: make(map[string]AttemptInfo)}
- )
- // AttemptInfo 登录尝试信息
- type AttemptInfo struct {
- Count int
- FirstTry time.Time
- LockedUntil *time.Time
- }
- // CheckLoginAttempts 检查登录尝试次数
- func CheckLoginAttempts(identifier string) (bool, string) {
- loginAttempts.RLock()
- info, exists := loginAttempts.m[identifier]
- loginAttempts.RUnlock()
- if !exists {
- return true, ""
- }
- // 检查是否被锁定
- if info.LockedUntil != nil && time.Now().Before(*info.LockedUntil) {
- remaining := info.LockedUntil.Sub(time.Now())
- return false, fmt.Sprintf("账户已锁定,请%.0f分钟后再试", remaining.Minutes())
- }
- // 检查尝试次数
- if info.Count >= 5 {
- // 锁定30分钟
- lockedUntil := time.Now().Add(30 * time.Minute)
- info.LockedUntil = &lockedUntil
- loginAttempts.Lock()
- loginAttempts.m[identifier] = info
- loginAttempts.Unlock()
- return false, "尝试次数过多,账户已锁定30分钟"
- }
- return true, ""
- }
- // RecordLoginAttempt 记录登录尝试
- func RecordLoginAttempt(identifier string, success bool) {
- loginAttempts.Lock()
- defer loginAttempts.Unlock()
- info, exists := loginAttempts.m[identifier]
- if success {
- // 登录成功,清除记录
- delete(loginAttempts.m, identifier)
- return
- }
- if !exists {
- // 第一次失败
- loginAttempts.m[identifier] = AttemptInfo{
- Count: 1,
- FirstTry: time.Now(),
- }
- } else {
- // 增加失败次数
- info.Count++
- loginAttempts.m[identifier] = info
- // 如果30分钟内失败5次,锁定账户
- if info.Count >= 5 && time.Since(info.FirstTry) <= 30*time.Minute {
- lockedUntil := time.Now().Add(30 * time.Minute)
- info.LockedUntil = &lockedUntil
- loginAttempts.m[identifier] = info
- }
- }
- // 清理30分钟前的记录
- for key, attemptInfo := range loginAttempts.m {
- if time.Since(attemptInfo.FirstTry) > 30*time.Minute {
- delete(loginAttempts.m, key)
- }
- }
- }
|