Files
trade/web/backend/internal/auth/jwt.go
2026-05-03 14:34:50 +08:00

56 lines
1.3 KiB
Go

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
}