加固后台管理安全

This commit is contained in:
yml2213
2026-06-11 07:23:00 +08:00
parent 5255b21141
commit 88b1df64e7
41 changed files with 1276 additions and 293 deletions
@@ -76,10 +76,12 @@ func (r *Repository) Create(ctx context.Context, req CreateAdminRequest) (*Admin
return nil, err
}
admin := model.AdminUser{
Username: req.Username,
PasswordHash: string(hash),
Nickname: req.Nickname,
Status: "active",
Username: req.Username,
PasswordHash: string(hash),
Nickname: req.Nickname,
Status: "active",
TokenVersion: 1,
PasswordMustChange: true,
}
if err := r.db.WithContext(ctx).Create(&admin).Error; err != nil {
return nil, err
@@ -102,6 +104,12 @@ func (r *Repository) Update(ctx context.Context, id uint64, req UpdateAdminReque
if err := db.Save(&admin).Error; err != nil {
return nil, err
}
if req.Status != "" {
if err := r.bumpTokenVersion(db, id); err != nil {
return nil, err
}
r.invalidatePermCache(ctx, id)
}
return r.FindByID(ctx, id)
}
@@ -150,7 +158,7 @@ func (r *Repository) AssignRoles(ctx context.Context, adminID uint64, roleIDs []
return err
}
}
return nil
return r.bumpTokenVersion(tx, adminID)
})
if err != nil {
return err
@@ -159,7 +167,7 @@ func (r *Repository) AssignRoles(ctx context.Context, adminID uint64, roleIDs []
return nil
}
func (r *Repository) ChangePassword(ctx context.Context, id uint64, oldPwd, newPwd string) error {
func (r *Repository) ChangeOwnPassword(ctx context.Context, id uint64, oldPwd, newPwd string) error {
var admin model.AdminUser
if err := r.db.WithContext(ctx).First(&admin, id).Error; err != nil {
return err
@@ -171,7 +179,35 @@ func (r *Repository) ChangePassword(ctx context.Context, id uint64, oldPwd, newP
if err != nil {
return err
}
return r.db.WithContext(ctx).Model(&admin).Update("password_hash", string(hash)).Error
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Model(&admin).Updates(map[string]any{
"password_hash": string(hash),
"password_must_change": false,
}).Error; err != nil {
return err
}
return r.bumpTokenVersion(tx, id)
})
}
func (r *Repository) ResetPassword(ctx context.Context, id uint64, newPwd string) error {
var admin model.AdminUser
if err := r.db.WithContext(ctx).First(&admin, id).Error; err != nil {
return err
}
hash, err := bcrypt.GenerateFromPassword([]byte(newPwd), bcrypt.DefaultCost)
if err != nil {
return err
}
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Model(&admin).Updates(map[string]any{
"password_hash": string(hash),
"password_must_change": true,
}).Error; err != nil {
return err
}
return r.bumpTokenVersion(tx, id)
})
}
func (r *Repository) GetPermissionCodes(ctx context.Context, adminID uint64) ([]string, error) {
@@ -223,6 +259,12 @@ func (r *Repository) invalidatePermCache(ctx context.Context, adminID uint64) {
r.redis.Del(ctx, permCacheKey(adminID))
}
func (r *Repository) bumpTokenVersion(db *gorm.DB, adminID uint64) error {
return db.Model(&model.AdminUser{}).
Where("id = ?", adminID).
UpdateColumn("token_version", gorm.Expr("token_version + 1")).Error
}
func permCacheKey(adminID uint64) string {
return fmt.Sprintf("admin:perms:%d", adminID)
}