live-sfu-demo/internal/auth/jwt.go

71 lines
1.5 KiB
Go

package auth
import (
"errors"
"time"
"github.com/golang-jwt/jwt/v5"
)
type Claims struct {
Username string `json:"username"`
Role string `json:"role"`
jwt.RegisteredClaims
}
type JWTManager struct {
secret []byte
ttl time.Duration
issuer string
}
func NewJWTManager(secret string, ttl time.Duration) *JWTManager {
if secret == "" {
secret = "insecure-jwt-secret-change-me"
}
if ttl == 0 {
ttl = 2 * time.Hour
}
return &JWTManager{secret: []byte(secret), ttl: ttl, issuer: "live-sfu-demo"}
}
func (j *JWTManager) Sign(username, role string) (string, error) {
now := time.Now()
claims := Claims{
Username: username,
Role: role,
RegisteredClaims: jwt.RegisteredClaims{
Issuer: j.issuer,
Subject: username,
IssuedAt: jwt.NewNumericDate(now),
ExpiresAt: jwt.NewNumericDate(now.Add(j.ttl)),
NotBefore: jwt.NewNumericDate(now),
},
}
tok := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return tok.SignedString(j.secret)
}
func (j *JWTManager) Verify(tokenStr string) (*Claims, error) {
if tokenStr == "" {
return nil, errors.New("empty token")
}
tok, err := jwt.ParseWithClaims(tokenStr, &Claims{}, func(t *jwt.Token) (interface{}, error) {
if t.Method != jwt.SigningMethodHS256 {
return nil, errors.New("unexpected signing method")
}
return j.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
}
func (j *JWTManager) TTL() time.Duration { return j.ttl }