core/middleware/middleware.go
2024-02-19 20:48:04 +03:00

81 lines
1.9 KiB
Go

package middleware
import (
"github.com/gofiber/fiber/v2"
"os"
"strings"
"time"
"github.com/golang-jwt/jwt/v5"
)
const (
AccountId = "id"
)
func JWTAuth() fiber.Handler {
return func(c *fiber.Ctx) error {
authHeader := c.Get("Authorization")
if authHeader == "" {
c.Status(fiber.StatusUnauthorized).SendString("no JWT found")
return nil
}
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
if tokenString == authHeader {
c.Status(fiber.StatusUnauthorized).SendString("invalid JWT Header: missing Bearer")
return nil
}
publicKey := os.Getenv("PUBLIC_ACCESS_SECRET_KEY")
if publicKey == "" {
// TODO log
c.Status(fiber.StatusInternalServerError).SendString("public key not found")
return nil
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return jwt.ParseRSAPublicKeyFromPEM([]byte(publicKey))
})
if err != nil {
c.Status(fiber.StatusUnauthorized).SendString("invalid JWT")
return nil
}
if token.Valid {
expirationTime, err := token.Claims.GetExpirationTime()
if err != nil {
c.Status(fiber.StatusUnauthorized).SendString("no expiration time in JWT")
return nil
}
if time.Now().Unix() >= expirationTime.Unix() {
c.Status(fiber.StatusUnauthorized).SendString("expired JWT")
return nil
}
} else {
c.Status(fiber.StatusUnauthorized).SendString("invalid JWT")
return nil
}
m, ok := token.Claims.(jwt.MapClaims)
if !ok {
c.Status(fiber.StatusInternalServerError).SendString("broken token claims")
return nil
}
id, ok := m["id"].(string)
if !ok || id == "" {
c.Status(fiber.StatusUnauthorized).SendString("missing id claim in JWT")
return nil
}
c.Context().SetUserValue(AccountId, id)
return c.Next()
}
}
func GetAccountId(c *fiber.Ctx) (string, bool) {
id, ok := c.Context().UserValue(AccountId).(string)
return id, ok
}