公开密码登录口按 IP 限制 10 分钟内最多 20 次失败,堵住未授权爆破。metric 持平 8。

Result: {"status":"keep","total_issues":8,"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":1,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":8,"eslint_problems":0,"eslint_errors":0,"eslint_warnings":0,"tsc_errors":0,"measure_s":85,"golint_test_testifylint":0,"golint_test_thelper":0,"golint_test_usetesting":0,"golint_test_total":0,"golint_exhaustive":0,"golint_vetx_total":0,"vitest_failed":0,"vitest_total":126}
This commit is contained in:
ryan
2026-08-25 23:11:05 +08:00
parent c9fc9c0eea
commit d73aa5f9f0
4 changed files with 52 additions and 0 deletions
+8
View File
@@ -68,6 +68,10 @@ func Login(c *gin.Context) {
response.AbortBadRequest(c, errPasswordLoginDisabled)
return
}
if loginAttemptsBlocked(ctx, c.ClientIP()) {
response.AbortBadRequest(c, errLoginRateLimited)
return
}
var req loginRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.AbortBadRequest(c, err.Error())
@@ -82,11 +86,13 @@ func Login(c *gin.Context) {
user, err := getUserByUsernameOrEmail(ctx, req.Username)
if err != nil {
pkgu.DummyCheckPassword(req.Password)
recordFailedLogin(ctx, c.ClientIP())
logger.WarnF(ctx, "[LoginAudit] failed login attempt (username not found) for input: %s, IP: %s", req.Username, c.ClientIP())
response.AbortBadRequest(c, errUsernameOrPasswordWrong)
return
}
if !user.IsActive {
recordFailedLogin(ctx, c.ClientIP())
logger.WarnF(ctx, "[LoginAudit] banned user login attempt for username: %s, ID: %d, IP: %s", user.Username, user.ID, c.ClientIP())
response.AbortBadRequest(c, errUsernameOrPasswordWrong)
return
@@ -96,6 +102,7 @@ func Login(c *gin.Context) {
isPlaintext := !user.IsPasswordEncrypted()
if !user.CheckPassword(req.Password) {
recordFailedLogin(ctx, c.ClientIP())
logger.WarnF(ctx, "[LoginAudit] failed login attempt (incorrect password) for username: %s, ID: %d, IP: %s", user.Username, user.ID, c.ClientIP())
response.AbortBadRequest(c, errUsernameOrPasswordWrong)
return
@@ -124,6 +131,7 @@ func Login(c *gin.Context) {
if isPlaintext {
extras["need_change_password"] = true
}
clearFailedLogins(ctx, c.ClientIP())
if err := oauth.SetLoginSession(ctx, c, user, extras); err != nil {
response.AbortBadRequest(c, errSaveSessionFailed)
return