backend requirements onthe xustomer app
This commit is contained in:
@@ -2,6 +2,8 @@ package middlewares
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -37,8 +39,7 @@ func Idempotency() fiber.Handler {
|
||||
if key == "" || db.Rdb == nil {
|
||||
return c.Next()
|
||||
}
|
||||
uid, _ := c.Locals("userid").(int)
|
||||
base := fmt.Sprintf("idem:%d:%s", uid, key)
|
||||
base := "idem:" + idempotencyScope(c) + ":" + key
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
@@ -80,3 +81,32 @@ func Idempotency() fiber.Handler {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// idempotencyScope namespaces a key so one caller's stored response can never
|
||||
// be replayed to another.
|
||||
//
|
||||
// For an authenticated request the caller's own user id is the scope, which is
|
||||
// what this middleware has always used.
|
||||
//
|
||||
// An UNAUTHENTICATED request has no user id, and defaulting to 0 would put
|
||||
// every anonymous caller in one namespace: two customers who happened to pick
|
||||
// the same Idempotency-Key on POST /customer/auth/otp/verify would collide, and
|
||||
// the second would be handed the first's access token, refresh token and
|
||||
// customer record. So an anonymous request is scoped by the request path and a
|
||||
// hash of its body instead — the same body replays, a different body does not,
|
||||
// and one person's session can never be served to another.
|
||||
// The authenticated form is byte-identical to what this middleware has always
|
||||
// produced ("idem:<uid>:<key>"). Changing it would orphan every in-flight key
|
||||
// in Redis at deploy time, and a rider retrying a pickup-complete across that
|
||||
// boundary would execute it a second time instead of replaying — the exact
|
||||
// double-collection this middleware exists to prevent.
|
||||
func idempotencyScope(c *fiber.Ctx) string {
|
||||
if uid, ok := c.Locals("userid").(int); ok && uid != 0 {
|
||||
return fmt.Sprintf("%d", uid)
|
||||
}
|
||||
// Anonymous callers get their own namespace shape, which no previous key
|
||||
// can collide with: every key written before this change had a numeric
|
||||
// scope, and this one never is.
|
||||
sum := sha256.Sum256(append([]byte(c.Path()+"\x00"), c.Body()...))
|
||||
return "anon-" + hex.EncodeToString(sum[:16])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user