feat: 建立可靠通知、吊销与跨实例状态
This commit is contained in:
@@ -72,7 +72,7 @@ func registerHandler(db *gorm.DB, cfg *config.Config) gin.HandlerFunc {
|
||||
}
|
||||
|
||||
// 强制角色为 viewer,防止垂直越权(注册接口不允许自选角色)
|
||||
role := model.RoleViewer
|
||||
role := model.RoleViewer
|
||||
user := model.User{
|
||||
Username: body.Username,
|
||||
Email: body.Email,
|
||||
@@ -123,13 +123,19 @@ func loginHandler(db *gorm.DB, cfg *config.Config) gin.HandlerFunc {
|
||||
|
||||
var user model.User
|
||||
if db.Where("username = ? OR email = ?", body.Username, body.Username).First(&user).Error != nil {
|
||||
middleware.RecordLoginFail(c, body.Username)
|
||||
if err := middleware.RecordLoginFail(c, body.Username); err != nil {
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "用户名或密码错误"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(body.Password)); err != nil {
|
||||
middleware.RecordLoginFail(c, body.Username)
|
||||
if err := middleware.RecordLoginFail(c, body.Username); err != nil {
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "用户名或密码错误"})
|
||||
return
|
||||
}
|
||||
@@ -140,7 +146,10 @@ func loginHandler(db *gorm.DB, cfg *config.Config) gin.HandlerFunc {
|
||||
}
|
||||
|
||||
// 登录成功,清空失败计数
|
||||
middleware.RecordLoginSuccess(c, body.Username)
|
||||
if err := middleware.RecordLoginSuccess(c, body.Username); err != nil {
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// 记录审计日志
|
||||
uid := user.ID
|
||||
@@ -184,7 +193,12 @@ func refreshHandler(db *gorm.DB, cfg *config.Config) gin.HandlerFunc {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "刷新令牌无效"})
|
||||
return
|
||||
}
|
||||
if middleware.IsRevoked(claims) {
|
||||
revoked, err := middleware.IsRevoked(claims)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "认证状态服务不可用"})
|
||||
return
|
||||
}
|
||||
if revoked {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "刷新令牌已注销"})
|
||||
return
|
||||
}
|
||||
@@ -201,7 +215,10 @@ func refreshHandler(db *gorm.DB, cfg *config.Config) gin.HandlerFunc {
|
||||
}
|
||||
|
||||
// 吊销旧刷新令牌(一次性使用),签发新令牌对
|
||||
middleware.RevokeToken(claims, body.RefreshToken, claims.ExpiresAt.Time)
|
||||
if err := middleware.RevokeToken(claims, body.RefreshToken, claims.ExpiresAt.Time); err != nil {
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, buildLoginPayload(db, user, cfg))
|
||||
}
|
||||
}
|
||||
@@ -214,7 +231,10 @@ func logoutHandler(cfg *config.Config) gin.HandlerFunc {
|
||||
if len(parts) == 2 && strings.EqualFold(parts[0], "Bearer") {
|
||||
if claims, token, err := middleware.ExtractClaims(parts[1], cfg.JWTSecret); err == nil && token.Valid {
|
||||
if claims.ExpiresAt != nil {
|
||||
middleware.RevokeToken(claims, parts[1], claims.ExpiresAt.Time)
|
||||
if err := middleware.RevokeToken(claims, parts[1], claims.ExpiresAt.Time); err != nil {
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user