فهرست منبع

middleware

- add X-Instance-ID
- refactor jwt
Alexey Kim 1 سال پیش
والد
کامیت
27ee0d5421
7فایلهای تغییر یافته به همراه86 افزوده شده و 30 حذف شده
  1. 0 30
      config/jwt.go
  2. 2 0
      devops/router.yaml
  3. 1 0
      go.mod
  4. 2 0
      go.sum
  5. 8 0
      middleware/context_key.go
  6. 39 0
      middleware/instance.go
  7. 34 0
      middleware/jwt.go

+ 0 - 30
config/jwt.go

@@ -1,30 +0,0 @@
-package config
-
-import (
-	"context"
-	"github.com/golang-jwt/jwt/v5"
-	"github.com/labstack/echo-jwt/v4"
-	"github.com/labstack/echo/v4"
-)
-
-const ctxKeyJwt = "echo.ctx.jwt"
-
-func (c Configuration) EchoJwtMiddleware() echo.MiddlewareFunc {
-	return echojwt.WithConfig(echojwt.Config{
-		ContextKey: ctxKeyJwt,
-		SigningKey: []byte(c.SecretKey),
-		SuccessHandler: func(ctx echo.Context) {
-			val := context.WithValue(ctx.Request().Context(), ctxKeyJwt, ctx.Get(ctxKeyJwt))
-			ctx.SetRequest(ctx.Request().WithContext(val))
-		},
-	})
-}
-
-func Token(ctx context.Context) *jwt.Token {
-	t, ok := ctx.Value(ctxKeyJwt).(*jwt.Token)
-	if !ok {
-		return nil
-	}
-
-	return t
-}

+ 2 - 0
devops/router.yaml

@@ -18,6 +18,8 @@ headers:
     request:
       - propagate:
           named: "Authorization"
+      - propagate:
+          named: "X-Instance-ID"
 
 traffic_shaping:
   deduplicate_variables: true

+ 1 - 0
go.mod

@@ -3,6 +3,7 @@ module beejay.kim/craft/api
 go 1.20
 
 require (
+	github.com/gofrs/uuid v4.4.0+incompatible
 	github.com/golang-jwt/jwt/v5 v5.0.0
 	github.com/labstack/echo-jwt/v4 v4.2.0
 	github.com/labstack/echo/v4 v4.11.1

+ 2 - 0
go.sum

@@ -3,6 +3,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
+github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
 github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
 github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=

+ 8 - 0
middleware/context_key.go

@@ -0,0 +1,8 @@
+package middleware
+
+type ctxKey string
+
+const (
+	keyInstanceId ctxKey = "ctx.instance.id"
+	keyJwtToken   ctxKey = "ctx.jwt.token"
+)

+ 39 - 0
middleware/instance.go

@@ -0,0 +1,39 @@
+package middleware
+
+import (
+	"context"
+	"fmt"
+	"github.com/gofrs/uuid"
+	"github.com/labstack/echo/v4"
+	"net/http"
+)
+
+func InstanceId() echo.MiddlewareFunc {
+	return func(next echo.HandlerFunc) echo.HandlerFunc {
+		return func(c echo.Context) error {
+			s := c.Request().Header.Get("X-Instance-ID")
+			if s == "" {
+				return echo.NewHTTPError(http.StatusForbidden, "missing or malformed instance id")
+			}
+
+			id, err := uuid.FromString(s)
+			if err != nil {
+				return echo.NewHTTPError(http.StatusForbidden, "missing or malformed instance id")
+			}
+
+			value := context.WithValue(c.Request().Context(), keyInstanceId, id)
+			c.SetRequest(c.Request().WithContext(value))
+
+			return nil
+		}
+	}
+}
+
+func GetInstanceId(ctx context.Context) (uuid.UUID, error) {
+	id, ok := ctx.Value(keyInstanceId).(uuid.UUID)
+	if !ok {
+		return uuid.Nil, fmt.Errorf("missing or malformed instance id")
+	}
+
+	return id, nil
+}

+ 34 - 0
middleware/jwt.go

@@ -0,0 +1,34 @@
+package middleware
+
+import (
+	"context"
+	"fmt"
+	"github.com/golang-jwt/jwt/v5"
+	echojwt "github.com/labstack/echo-jwt/v4"
+	"github.com/labstack/echo/v4"
+)
+
+func Jwt(secret []byte) echo.MiddlewareFunc {
+	var (
+		sKeyJwtToken = fmt.Sprintf("%s", keyJwtToken)
+		cfg          = echojwt.Config{
+			ContextKey: sKeyJwtToken,
+			SigningKey: secret,
+			SuccessHandler: func(ctx echo.Context) {
+				value := context.WithValue(ctx.Request().Context(), keyJwtToken, ctx.Get(sKeyJwtToken))
+				ctx.SetRequest(ctx.Request().WithContext(value))
+			},
+		}
+	)
+
+	return echojwt.WithConfig(cfg)
+}
+
+func GetToken(ctx context.Context) (*jwt.Token, error) {
+	t, ok := ctx.Value(keyJwtToken).(*jwt.Token)
+	if !ok {
+		return nil, fmt.Errorf("missing or malformed token")
+	}
+
+	return t, nil
+}