Files
api_tmpl/internal/auth/paseto_maker.go
T
2026-01-08 01:15:07 +00:00

98 lines
2.2 KiB
Go

package auth
import (
"strings"
"time"
"aidanwoods.dev/go-paseto"
"github.com/FernandoJVideira/simple_bank/internal/config"
"github.com/google/uuid"
)
type PasetoMaker struct {
config config.Config
symmetricKey paseto.V4SymmetricKey
implicit []byte
}
func NewPasetoMaker(config config.Config) (Maker, error) {
maker := &PasetoMaker{
config: config,
symmetricKey: paseto.NewV4SymmetricKey(),
implicit: []byte("implicit"),
}
return maker, nil
}
func (maker *PasetoMaker) CreateToken(username string, role string, duration time.Duration) (string, *Payload, error) {
payload, err := NewPayload(username, role, duration)
if err != nil {
return "", nil, err
}
token := paseto.NewToken()
token.SetIssuedAt(payload.IssuedAt)
token.SetExpiration(payload.ExpiredAt)
token.SetString("role", payload.Role)
token.SetAudience(maker.config.TokenAUD)
token.SetIssuer(maker.config.TokenISS)
token.SetSubject(payload.Username)
token.SetJti(payload.ID.String())
signedToken := token.V4Encrypt(maker.symmetricKey, maker.implicit)
return signedToken, payload, nil
}
func (maker *PasetoMaker) VerifyToken(token string) (*Payload, error) {
parser := paseto.NewParser()
parser.AddRule(paseto.NotExpired())
parsedToken, err := parser.ParseV4Local(maker.symmetricKey, token, maker.implicit)
if err != nil {
if strings.Contains(err.Error(), "token has expired") {
return nil, ErrExpiredToken
}
return nil, ErrInvalidToken
}
payload, err := parseClaims(parsedToken)
if err != nil {
return nil, err
}
return payload, nil
}
func parseClaims(t *paseto.Token) (*Payload, error) {
id, err := t.GetJti()
if err != nil {
return nil, ErrInvalidToken
}
username, err := t.GetSubject()
if err != nil {
return nil, ErrInvalidToken
}
role, err := t.GetString("role")
if err != nil {
return nil, ErrInvalidToken
}
issuedAt, err := t.GetIssuedAt()
if err != nil {
return nil, ErrInvalidToken
}
expiredAt, err := t.GetExpiration()
if err != nil {
return nil, ErrInvalidToken
}
payload := &Payload{
ID: uuid.MustParse(id),
Username: username,
Role: role,
IssuedAt: issuedAt,
ExpiredAt: expiredAt,
}
return payload, nil
}