gut/irisutils/auth/jwt.go
2024-02-17 22:46:50 +01:00

89 lines
1.8 KiB
Go

package auth
import (
"time"
"github.com/kataras/golog"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/jwt"
"github.com/kataras/iris/v12/sessions"
"golang.org/x/crypto/bcrypt"
)
type JWTAuthOption func(j *JWTAuth)
type StandardClaim struct {
Name string `json:"name"`
}
func defaultClaim() any {
return new(StandardClaim)
}
type JWTAuth struct {
signer *jwt.Signer
claimFn func() any
Middleware func(ctx iris.Context)
}
func NewJWTAuth(secret string, lifeTime time.Duration, options ...JWTAuthOption) *JWTAuth {
secretBytes := []byte(secret)
j := &JWTAuth{
signer: jwt.NewSigner(jwt.HS256, secretBytes, lifeTime),
claimFn: defaultClaim,
}
for _, jo := range options {
jo(j)
}
verifier := jwt.NewVerifier(jwt.HS256, secretBytes)
verifier.WithDefaultBlocklist()
extractor := func(ctx iris.Context) string {
session := sessions.Get(ctx)
return session.GetString("token")
}
verifier.Extractors = append(verifier.Extractors, extractor)
j.Middleware = verifier.Verify(func() any {
return j.claimFn()
})
return j
}
func WithCustomClaim(fn func() any) JWTAuthOption {
return func(j *JWTAuth) {
j.claimFn = fn
}
}
func (j *JWTAuth) Sign(claim any) ([]byte, error) {
return j.signer.Sign(claim)
}
func (j *JWTAuth) GenerateRandomSecret() string {
return j.HashAndSalt(string(jwt.MustGenerateRandom(64)))
}
func (j *JWTAuth) HashAndSalt(pwd string) string {
hash, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
if err != nil {
golog.Fatalf("Failed to hash password: %v", err)
}
return string(hash)
}
func (j *JWTAuth) ComparePasswords(hashedPwd string, plainPwd string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hashedPwd), []byte(plainPwd))
if err != nil {
return false
}
return true
}