c.IP() detrás del proxy del hosting devuelve la IP interna del contenedor que reenvía (10.x.x.x). Contra eso, ninguna IP pública cargada en una llave podía coincidir: toda API key con restricción de IP daba 403, que es exactamente lo que le pasó a la integración de vCard. Ahora se lee X-Forwarded-For, y se toma la ÚLTIMA entrada, no la primera: con un proxy adelante esa es la que escribió el proxy. Si quien llama manda su propio X-Forwarded-For, el proxy le agrega la IP real al final — quedarse con la primera sería dejar que cada uno declare su IP y la restricción no valdría nada. El test fija ese caso. Mismo arreglo en la autenticación de Pagos Externos, que comparaba igual. El 403 ahora dice qué IP se vio y cuál está permitida: sin eso, del otro lado se prueba a ciegas. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
49 lines
1.2 KiB
Go
49 lines
1.2 KiB
Go
package middlewares
|
|
|
|
import (
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
func TestIPDelCliente(t *testing.T) {
|
|
casos := []struct {
|
|
nombre string
|
|
xff string
|
|
real string
|
|
want string
|
|
}{
|
|
{"un solo proxy", "46.202.93.92", "", "46.202.93.92"},
|
|
// Si quien llama manda su propio X-Forwarded-For, el proxy le agrega la
|
|
// IP real al final. Quedarse con la primera sería dejar que elija su IP.
|
|
{"cliente intentando falsear", "1.2.3.4, 46.202.93.92", "", "46.202.93.92"},
|
|
{"con espacios", " 10.0.0.1 , 46.202.93.92 ", "", "46.202.93.92"},
|
|
{"sin xff, con x-real-ip", "", "46.202.93.92", "46.202.93.92"},
|
|
}
|
|
|
|
app := fiber.New()
|
|
app.Get("/ip", func(c *fiber.Ctx) error {
|
|
return c.SendString(IPDelCliente(c))
|
|
})
|
|
|
|
for _, cs := range casos {
|
|
req := httptest.NewRequest("GET", "/ip", nil)
|
|
if cs.xff != "" {
|
|
req.Header.Set("X-Forwarded-For", cs.xff)
|
|
}
|
|
if cs.real != "" {
|
|
req.Header.Set("X-Real-Ip", cs.real)
|
|
}
|
|
resp, err := app.Test(req)
|
|
if err != nil {
|
|
t.Fatalf("%s: %v", cs.nombre, err)
|
|
}
|
|
buf := make([]byte, 64)
|
|
n, _ := resp.Body.Read(buf)
|
|
if got := string(buf[:n]); got != cs.want {
|
|
t.Errorf("%s: IPDelCliente = %q, want %q", cs.nombre, got, cs.want)
|
|
}
|
|
}
|
|
}
|