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 }