feat: adjust deploy password and login limit

This commit is contained in:
engigu
2026-02-10 14:19:32 +08:00
parent 70a66c4693
commit b855400cec
6 changed files with 67 additions and 5 deletions
+32
View File
@@ -2,6 +2,8 @@ package controllers
import (
"strconv"
"sync"
"time"
"github.com/engigu/baihu-panel/internal/constant"
"github.com/engigu/baihu-panel/internal/middleware"
@@ -17,6 +19,13 @@ type AuthController struct {
loginLogService *services.LoginLogService
}
type loginAttempt struct {
Count int
LastAttempt time.Time
}
var loginAttempts sync.Map
func NewAuthController(userService *services.UserService, settingsService *services.SettingsService, loginLogService *services.LoginLogService) *AuthController {
return &AuthController{
userService: userService,
@@ -39,14 +48,37 @@ func (ac *AuthController) Login(c *gin.Context) {
return
}
// 暴力破解防御
if val, ok := loginAttempts.Load(ip); ok {
attempt := val.(*loginAttempt)
if attempt.Count >= 5 && time.Since(attempt.LastAttempt) < time.Minute {
ac.loginLogService.Create(req.Username, ip, userAgent, "failed", "尝试次数过多,请一分钟后再试")
utils.TooManyRequests(c, "尝试次数过多,请一分钟后再试")
return
}
// 如果距离上次尝试已超过一分钟,重置计数
if time.Since(attempt.LastAttempt) >= time.Minute {
loginAttempts.Delete(ip)
}
}
user := ac.userService.GetUserByUsername(req.Username)
if user == nil || !ac.userService.ValidatePassword(user, req.Password) {
// 记录失败尝试
val, _ := loginAttempts.LoadOrStore(ip, &loginAttempt{Count: 0, LastAttempt: time.Now()})
attempt := val.(*loginAttempt)
attempt.Count++
attempt.LastAttempt = time.Now()
// 记录登录失败日志
ac.loginLogService.Create(req.Username, ip, userAgent, "failed", "用户名或密码错误")
utils.Unauthorized(c, "用户名或密码错误")
return
}
// 登录成功,清除尝试记录
loginAttempts.Delete(ip)
// 获取 cookie 过期天数
expireDays := 7
if days := ac.settingsService.Get(constant.SectionSite, constant.KeyCookieDays); days != "" {
+9 -2
View File
@@ -2,6 +2,7 @@ package services
import (
"github.com/engigu/baihu-panel/internal/logger"
"github.com/engigu/baihu-panel/internal/utils"
)
type InitService struct {
@@ -40,6 +41,12 @@ func (s *InitService) initializeAdmin(userService *UserService) {
return
}
userService.CreateUser("admin", "123456", "admin@local", "admin")
logger.Info("管理员账号创建成功: admin / 123456")
password := utils.RandomString(12)
userService.CreateUser("admin", password, "admin@local", "admin")
logger.Infof("--------------------------------------------------")
logger.Infof("管理员账号创建成功:")
logger.Infof("用户名: admin")
logger.Infof("密 码: %s", password)
logger.Infof("请妥善保管您的密码,并登录后及时修改。")
logger.Infof("--------------------------------------------------")
}
+18
View File
@@ -0,0 +1,18 @@
package utils
import (
"crypto/rand"
"math/big"
)
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// RandomString 生成指定长度的随机字符串
func RandomString(n int) string {
b := make([]byte, n)
for i := range b {
num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
b[i] = charset[num.Int64()]
}
return string(b)
}
+4
View File
@@ -50,6 +50,10 @@ func NotFound(c *gin.Context, msg string) {
Error(c, 404, msg)
}
func TooManyRequests(c *gin.Context, msg string) {
Error(c, 429, msg)
}
func ServerError(c *gin.Context, msg string) {
Error(c, 500, msg)
}