Obtener el nombre de host de la solicitud actual en node.js Express

175

Por lo tanto, es posible que me falte algo simple aquí, pero parece que no puedo encontrar una manera de obtener el nombre de host para el que se solicitó un objeto de solicitud al que estoy enviando una respuesta.

¿Es posible averiguar qué nombre de host está visitando actualmente el usuario desde node.js?

Jesse
fuente
Está en los encabezados de solicitud. Bueno, eso pensé pero ahora no lo veo ... hmmmm
jcolebrand
8
CJohn lo encontró, está dentro request.headers.host, ¡gracias!
Jesse
Pensé que sí ... simplemente no lo estaba sacando de la nada. ¡Me alegra que lo hayas conseguido!
jcolebrand
@Jesse Hola, eso en realidad no es correcto. request.headers.host no es el nombre de host del servidor basado en el sistema operativo, es el nombre del encabezado del host enviado junto con la solicitud HTTP. Si su servidor responde a cualquier solicitud HTTP, independientemente del encabezado del host, ese valor podría ser CUALQUIER COSA que el cliente decida enviar.
Rob Evans,
@RobEvans: si lees la última línea de la pregunta, eso es exactamente lo que estaba buscando. Un cliente que envía un encabezado de nombre de host falso es un caso de uso extraño que no me preocuparía personalmente por tratar de admitir.
Jesse

Respuestas:

198

Si está hablando de una solicitud HTTP, puede encontrar el host de solicitud en:

request.headers.host

Pero eso se basa en una solicitud entrante.

Más en http://nodejs.org/docs/v0.4.12/api/http.html#http.ServerRequest

Si está buscando información de máquina / nativa, pruebe el objeto de proceso.

cjohn
fuente
66
Ah, increíble: FWIW, no habría forma de detectar el host real sin una solicitud, podría tener varios hosts configurados, ¡pero esto es lo que estaba buscando!
Jesse
2
Hizo el truco, gracias! En Express 4, tuve que hacer esta actualización: req.headers.host
Gene Bo
55
¡Incorrecto! request.headers.hostdevuelve http://127.0.0.1pero no un nombre de dominio del servidor de producción
Verde
10
req.headers.hostes proporcionado por el usuario. Puedo elaborar una solicitud en 1 línea de python y enviarle una solicitud sin que ese campo haga que su código se bloquee
arboreal84
1
request.headers.host ahora está en desuso, en su lugar puede usar request.headers.hostname
Syam Danda
281

Puede usar el módulo os:

var os = require("os");
os.hostname();

Ver http://nodejs.org/docs/latest/api/os.html#os_os_hostname

Advertencias:

  1. si puede trabajar con la dirección IP: las máquinas pueden tener varias tarjetas de red y, a menos que lo especifique, el nodo las escuchará en todas, por lo que no sabe en qué NIC ingresó la solicitud antes de que entre.

  2. El nombre de host es una cuestión de DNS: no olvide que varios alias de DNS pueden apuntar a la misma máquina.

stephenbez
fuente
66
Aunque esto funcionará para obtener el nombre de host de la máquina, puedo tener una máquina configurada para responder a múltiples hosts, por lo que esto no sería exacto.
Jesse
77
Sin embargo, este es mejor, porque puede usarlo en módulos que no se ejecutan siempre dentro del contexto de la aplicación HTTP
Radagast the Brown el
8
Y lo más importante, este responde la pregunta tal como fue escrita. Creo que la pregunta es realmente incorrecta si esta no es la respuesta.
Rob Evans
3
Esto se correlaciona con el hostnamecomando que debe ser un nombre DNS válido pero que no es obligatorio. Por ejemplo, en OS X obtendrá nombres como los my-machine.localque no se pueden resolver con DNS. Para determinar la IP externa de la máquina, deberá acceder a un servicio que realice esta función o utilizar el protocolo STUN para resolverlo.
tadman
66
Esto siempre es exacto. Devuelve el nombre de host de la máquina, que es el título de la pregunta formulada. (El texto de este hizo una pregunta diferente). El nombre de host utilizado en una solicitud HTTP entrante es un asunto diferente.
Cheeso
18

Aquí hay una alternativa

req.hostname

Lea sobre esto en Express Docs .

Eddie
fuente
1
Esta es la respuesta correcta, ya que req.headers.host le da host: port
ekerner
¿Cuál es la diferencia entre req.hostname y req.host?
RayLoveless
1
req.host está en desuso. Si usa eso, express emitirá una advertencia que dice 'req.host en desuso: use req.hostname en su lugar'
bruceczk
8

Si necesita un nombre de dominio completo y no tiene una solicitud HTTP, en Linux, puede usar:

var child_process = require("child_process");

child_process.exec("hostname -f", function(err, stdout, stderr) {
  var hostname = stdout.trim();
});
dricket
fuente
1
Por cierto, también hay un hostnamecomando en Windows (pero lo
invocas
7

En primer lugar, antes de dar una respuesta, me gustaría ser sincero sobre el hecho de que al confiar en los encabezados está abriendo la puerta a vulnerabilidades de seguridad como el phishing. Por lo tanto, para fines de redireccionamiento, no use valores de encabezados sin primero validar que la URL esté autorizada.

Entonces, el nombre de host de su sistema operativo podría no coincidir necesariamente con el DNS. De hecho, una IP puede tener más de un nombre DNS. Por lo tanto, para fines HTTP no hay garantía de que el nombre de host asignado a su máquina en la configuración de su sistema operativo sea utilizable.

La mejor opción que puedo pensar es obtener su IP pública de escucha HTTP y resolver su nombre a través de DNS. Vea el dns.reversemétodo para más información. Pero, de nuevo, tenga en cuenta que una IP puede tener múltiples nombres asociados.

arboreal84
fuente