package service import ( "context" "errors" "time" "github.com/golang-jwt/jwt/v5" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" "pay-bridge/internal/repository" ) type AdminAuthService struct { repo *repository.AdminUserRepository jwtSecret []byte expireHrs int } func NewAdminAuthService(repo *repository.AdminUserRepository, jwtSecret string, expireHours int) *AdminAuthService { return &AdminAuthService{ repo: repo, jwtSecret: []byte(jwtSecret), expireHrs: expireHours, } } // Login 验证用户名密码,成功返回 JWT token func (s *AdminAuthService) Login(ctx context.Context, username, password string) (string, error) { user, err := s.repo.GetByUsername(ctx, username) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return "", errors.New("用户名或密码错误") } return "", err } if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil { return "", errors.New("用户名或密码错误") } claims := jwt.MapClaims{ "username": user.Username, "exp": time.Now().Add(time.Duration(s.expireHrs) * time.Hour).Unix(), "iat": time.Now().Unix(), } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString(s.jwtSecret) } // ParseToken 验证并解析 JWT,返回用户名 func (s *AdminAuthService) ParseToken(tokenStr string) (string, error) { token, err := jwt.Parse(tokenStr, func(t *jwt.Token) (any, error) { if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { return nil, errors.New("invalid signing method") } return s.jwtSecret, nil }, jwt.WithValidMethods([]string{"HS256"})) if err != nil { return "", err } claims, ok := token.Claims.(jwt.MapClaims) if !ok || !token.Valid { return "", errors.New("invalid token") } username, ok := claims["username"].(string) if !ok { return "", errors.New("invalid token claims") } return username, nil }