Si alguien envía una solicitud XHR desde some-client.com a some-rest.com, quiero obtener el origen ( nombre de dominio, no IP del cliente ) de la solicitud con PHP.

Las posibles soluciones:

  • Tal vez pueda usar $_SERVER['HTTP_ORIGIN'] pero no sé si es un estándar.
  • Veo otro encabezado como $_SERVER['HTTP_HOST'] o $_SERVER['SERVER_NAME'], pero en algunos casos esto devuelve el hostname real y no el domain real.
  • Y $_SERVER['REMOTE_ADDR'] da la IP del cliente.

¿Cuál es la forma correcta de obtener el origen de la solicitud, como un nombre de dominio con PHP?

¡Gracias!

8
Olaf 26 dic. 2016 a las 06:48

3 respuestas

La mejor respuesta

Según el artículo Control de acceso HTTP (CORS) por MDN:

Todas las solicitudes deben tener el encabezado Origin para que funcione correctamente bajo el mecanismo CORS ( Intercambio de recursos de origen cruzado ).

El encabezado de solicitud " Origen " es parte de RFC 6454 y lo describe como parte del mecanismo CORS y es compatible con todos los navegadores de acuerdo con MDN.

Descripción por MDN:

El encabezado de solicitud Origin indica de dónde se origina una búsqueda. Eso no incluye ninguna información de ruta, sino solo el nombre del servidor. Está enviado con solicitudes CORS, así como con solicitudes POST. Es similar al encabezado Referer, pero, a diferencia de este encabezado, no revela Todo el camino.

Fuente: https://developer.mozilla.org/en-US / docs / Web / HTTP / Headers / Origin

Ejemplo de MDN: ingrese la descripción de la imagen aquí

Entonces, para obtener el origen de la solicitud XHR con PHP, puede usar:

$_SERVER['HTTP_ORIGIN'] 

Y, en el caso de una solicitud directa, puede combinar HTTP_REFERER y REMOTE_ADDR como:

if (array_key_exists('HTTP_REFERER', $_SERVER)) {
    $origin = $_SERVER['HTTP_REFERER'];
} else {
    $origin = $_SERVER['REMOTE_ADDR'];
}

Entonces, la posible solución final es:

if (array_key_exists('HTTP_ORIGIN', $_SERVER)) {
    $origin = $_SERVER['HTTP_ORIGIN'];
}
else if (array_key_exists('HTTP_REFERER', $_SERVER)) {
    $origin = $_SERVER['HTTP_REFERER'];
} else {
    $origin = $_SERVER['REMOTE_ADDR'];
}

MDN es Mozilla Developer Network.

Muchas gracias por la ayuda @trine, @ waseem-bashir, @ p0lt10n y otras personas.

18
Olaf 26 dic. 2016 a las 18:37
$_SERVER['HTTP_ORIGIN']  // HTTP Origin header
$_SERVER['HTTP_HOST']    // HTTP Host header
$_SERVER['HTTP_REFERER'] // HTTP Referer header
$_SERVER['REMOTE_ADDR']  // HTTP Client's Public IP

Analicemos los parámetros $_SERVER anteriores.

Primero, XHR está en el lado del cliente y limita con un cliente http. Como los encabezados Origin y Referer no son obligatorios, un cliente que no sea un navegador web estándar no lo configurará. El siguiente encabezado de host puede no ser obligatorio. Si su servidor REST usa hosts virtuales, este encabezado es imprescindible para enrutar las solicitudes correctamente. Pero este encabezado no tiene ningún detalle sobre el cliente. La única cosa única para el cliente http es la IP pública. Pero esto corresponde a muchos clientes, ya que los ISP utilizan traducciones o proxies de direcciones de red.

Como todo es relativo y está dentro de los límites, CORS como mecanismos se construyen en el encabezado HTTP Origin. Se asume y se aconseja a los clientes que usen navegadores estándar.

En su caso, mi opinión es que está bien depender del encabezado Origin. Puede implementar CORS si le conviene.

1
TRiNE 26 dic. 2016 a las 04:52

En php puedes usar $ _SERVER ['HTTP_REFERER']. si está usando codeigniter, puede obtener el referente usando $ this-> agent-> is_referral ().

1
Waseem Bashir 26 dic. 2016 a las 04:10