package auth import ( "errors" "fmt" "time" "github.com/golang-jwt/jwt/v5" ) const tokenTTL = 12 * time.Hour type Claims struct { UserID int64 `json:"uid"` Username string `json:"usr"` Role string `json:"role"` jwt.RegisteredClaims } type Manager struct{ secret []byte } func NewManager(secret []byte) *Manager { return &Manager{secret: secret} } func (m *Manager) Issue(userID int64, username, role string) (string, time.Time, error) { exp := time.Now().Add(tokenTTL) claims := Claims{ UserID: userID, Username: username, Role: role, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(exp), IssuedAt: jwt.NewNumericDate(time.Now()), }, } tok := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) s, err := tok.SignedString(m.secret) return s, exp, err } func (m *Manager) Parse(tokenStr string) (*Claims, error) { tok, err := jwt.ParseWithClaims(tokenStr, &Claims{}, func(t *jwt.Token) (any, error) { if t.Method.Alg() != jwt.SigningMethodHS256.Alg() { return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) } return m.secret, nil }) if err != nil { return nil, err } claims, ok := tok.Claims.(*Claims) if !ok || !tok.Valid { return nil, errors.New("invalid token") } return claims, nil }