Obtener dominio actual

140

Tengo mi sitio en el servidor

http://www.myserver.uk.com

Para esto tengo dos dominios,

http://one.com

y

http://two.com

Me gustaría obtener el dominio actual de PHP, pero si lo uso $_SERVER['HTTP_HOST'], esto me mostrará

myserver.uk.com

en vez de:

one.com or two.com

¿Cómo puedo obtener el dominio, no el nombre del servidor?

Tengo PHP versión 5.2.

Tony Evyght
fuente
Solo puede obtener la URL primaria. ¿Cuál es primario de esos tres?
Code Spy
2
¿Exactamente cómo sus dos dominios 'redirigen' las solicitudes a su servidor?
xiaofeng.li
1
@infgeoax probablemente un marco ...
CodeCaster
primario es myserver.uk.com. Entonces, ¿cómo puedo obtener el nombre de dominio actual? Si abro el sitio con la dirección one.com, me gustaría obtener one.com en lugar de myserver.uk.com
Tony Evyght
@TonyEvyght ese es el punto infgeoax y trato de hacer, deberías obtener el nombre de host con el que te estás conectando $_SERVER['HTTP_HOST']. Si los sitios one.comy two.comestán "redirigiendo" utilizando un marco (i), la página en sí misma proviene de myserver.uk.com, por lo que no obtendrá el dominio real. ¿Para qué es la fuente HTML one.com?
CodeCaster

Respuestas:

175

Intenta usar esto: $_SERVER['SERVER_NAME']

O analizar

$_SERVER['REQUEST_URI']

apache_request_headers ()

una mitad
fuente
23
-1: Con esta respuesta sola, no sé exactamente cuáles son las diferentes sugerencias que estoy viendo. Claro, esto me da un punto para seguir buscando, pero en sí mismo realmente no es una buena respuesta ...
Jasper
44
simplemente print_r (apache_request_headers ()) y lo entenderás todo :)
mitad del
2
@SarahLewis HTTP_X_ORIGINAL_HOSTpuede ser modificado por el usuario y no se puede confiar en él. Esto puede no ser siempre un problema, pero es algo a tener en cuenta.
wp-overwatch.com
64

El mejor uso sería

echo $_SERVER['HTTP_HOST'];

Y se puede usar así:

if (strpos($_SERVER['HTTP_HOST'], 'banana.com') !== false) {
    echo "Yes this is indeed the banana.com domain";
}

Este código a continuación es una buena manera de ver todas las variables en $ _SERVER en una salida HTML estructurada con sus palabras clave resaltadas que se detiene directamente después de la ejecución. Como a veces olvido cuál usar yo mismo, creo que esto puede ser ingenioso.

<?php
    // Change banana.com to the domain you were looking for..
    $wordToHighlight = "banana.com";
    $serverVarHighlighted = str_replace( $wordToHighlight, '<span style=\'background-color:#883399; color: #FFFFFF;\'>'. $wordToHighlight .'</span>',  $_SERVER );
    echo "<pre>";
    print_r($serverVarHighlighted);
    echo "</pre>";
    exit();
?>
K. Kilian Lindberg
fuente
39

El uso de $_SERVER['HTTP_HOST']gets me (subdominio). Maindomain.extension. Parece la solución más fácil para mí.

Si realmente está 'redirigiendo' a través de un iFrame, puede agregar un parámetro GET que indique el dominio.

<iframe src="myserver.uk.com?domain=one.com"/>

Y luego puede establecer una variable de sesión que conserve estos datos en toda su aplicación.

Raz0rwire
fuente
1
lo más importante es que incluye el número de puerto para que no tenga que concatenarlo después. Sin embargo, phpinfo sugerido por bsdnoobz me ayuda a encontrar la solución correcta.
30

La única forma segura de hacerlo

Todas las otras respuestas en esta página tienen implicaciones de seguridad que debe tener en cuenta.

El único método seguro garantizado para recuperar el dominio actual es 𝓼𝓽𝓸𝓻𝓮 𝓲𝓽 𝓲𝓷 𝓪 𝓼𝓮𝓬𝓾𝓻𝓮 𝓵𝓸𝓬𝓪𝓽𝓲𝓸𝓷 𝔂𝓸𝓾𝓻𝓼𝓮𝓵𝓯.

La mayoría de los marcos se encargan de almacenar el dominio por usted, por lo que deberá consultar la documentación de su marco particular. Si no está utilizando un marco, considere almacenar el dominio en uno de los siguientes lugares:

+ ------------------------------------------------- --- + ----------------------------------- +
 | Métodos seguros de almacenamiento del dominio | Usado por |
+ ------------------------------------------------- --- + ----------------------------------- +
 | Un archivo de configuración | Joomla, Drupal / Symfony |
 El | La base de datos | WordPress |
 El | Una variable ambiental | Laravel |
 El | Un registro de servicio | Kubernetes DNS |
+ ------------------------------------------------- --- + ----------------------------------- +


Puedes usar lo siguiente ... pero son inseguros

Los hackers pueden hacer que estas variables generen el dominio que deseen. Esto puede provocar envenenamiento de caché y ataques de phishing apenas perceptibles.

$_SERVER['HTTP_HOST']

Esto obtiene el dominio de los encabezados de solicitud que están abiertos a la manipulación por parte de piratas informáticos . Lo mismo con:

$_SERVER['SERVER_NAME']

Esto puede mejorarse si la configuración de Apache usecanonicalname está desactivada; en cuyo caso $_SERVER['SERVER_NAME']ya no se permitirá que se rellenen con valores arbitrarios y será seguro. Sin embargo, esto no es predeterminado y no es tan común en una configuración.


En sistemas populares

A continuación se muestra cómo puede obtener el dominio actual en los siguientes marcos / sistemas:

WordPress

$urlparts = parse_url(home_url());
$domain = $urlparts['host'];

Si está construyendo una URL en WordPress, simplemente use home_url o site_url , o cualquiera de las otras funciones de URL .

Laravel

request()->getHost()

La request()->getHostfunción se hereda de Symfony y ha sido segura desde que se reparó el CVE-2013-4752 2013 .

Drupal

El instalador aún no se encarga de hacer esto seguro ( problema # 2404259 ). Pero en Drupal 8 hay documentación que puede seguir en la Configuración de host de confianza para asegurar su instalación de Drupal, después de lo cual se puede usar lo siguiente:

\Drupal::request()->getHost();

Otros marcos

Siéntase libre de editar esta respuesta para incluir cómo obtener el dominio actual en su marco favorito. Al hacerlo, incluya un enlace al código fuente relevante o cualquier otra cosa que me ayude a verificar que el marco está haciendo las cosas de forma segura.




Apéndice

Ejemplos de explotación:

  1. El envenenamiento de la memoria caché puede ocurrir si una botnet solicita continuamente una página con el encabezado de hosts incorrecto. El HTML resultante incluirá enlaces al sitio web de los atacantes donde pueden phishing a sus usuarios. Al principio, los enlaces maliciosos solo se enviarán de vuelta al hacker, pero si el hacker hace suficientes solicitudes, la versión maliciosa de la página terminará en su caché, donde se distribuirá a otros usuarios.

  2. Un ataque de phishing puede ocurrir si almacena enlaces en la base de datos en función del encabezado de los hosts. Por ejemplo, supongamos que almacena la URL absoluta en los perfiles de un usuario en un foro. Al usar el encabezado incorrecto, un hacker podría hacer que se envíe un sitio de phishing a cualquiera que haga clic en el enlace de su perfil.

  3. La intoxicación por restablecimiento de contraseña puede ocurrir si un pirata informático utiliza un encabezado de host malicioso al completar el formulario de restablecimiento de contraseña para un usuario diferente. Ese usuario recibirá un correo electrónico que contiene un enlace de restablecimiento de contraseña que conduce a un sitio de phishing.

  4. Aquí hay algunos ejemplos más maliciosos

Advertencias y notas adicionales:

  • Cuando usecanonicalname está desactivado, $_SERVER['SERVER_NAME']se rellena con el mismo encabezado $_SERVER['HTTP_HOST']que habría utilizado de todos modos (más el puerto). Esta es la configuración predeterminada de Apache. Si usted o Devops activan esto, entonces está bien, es decir, pero ¿realmente desea confiar en un equipo separado, o en usted mismo dentro de tres años, para mantener lo que parece ser una configuración menor en un -¿valor por defecto? Aunque esto hace que las cosas sean seguras, advertiría que no confíe en esta configuración.
  • Redhat, sin embargo, activa usecanonical por defecto [ fuente ].
  • Si se usa serverAlias en la entrada de hosts virtuales y se solicita el dominio con alias, $_SERVER['SERVER_NAME']no devolverá el dominio actual, pero devolverá el valor de la directiva serverName.
  • Si serverName no se puede resolver, el comando hostname del sistema operativo se usa en su lugar [fuente] .
  • Si se omite el encabezado del host, el servidor se comportará como si usecanonical estuviera en [fuente] .
  • Por último, intenté explotar esto en mi servidor local y no pude falsificar el encabezado de los hosts. No estoy seguro de si hubo una actualización de Apache que solucionó esto, o si simplemente estaba haciendo algo mal. En cualquier caso, este encabezado aún sería explotable en entornos donde no se utilizan hosts virtuales.

Little Rant:

     ¡Esta pregunta recibió cientos de miles de visitas sin una sola mención de los problemas de seguridad en cuestión! No debería ser así, pero solo porque una respuesta de desbordamiento de pila sea popular, eso no significa que sea segura.



wp-overwatch.com
fuente
1
Es posible que desee mencionar la diferencia entre home_url y site_url. wordpress.stackexchange.com/a/50605/13
Volomike
1
+1 para usuarios de WordPress. Es bueno si necesita examinar si está instalado en subdir, pero tenga en cuenta que la clave parse_url: $urlparts['path']no está establecida si está instalada en el directorio raíz del dominio. Else $urlparts['path']devuelve el subdirectorio.
Jonas Lundman el
9

Tratar $_SERVER['SERVER_NAME'].

Consejos: cree un archivo PHP que llame a la función phpinfo()y consulte la sección "Variables PHP". Hay un montón de variables útiles que nunca pensamos allí.

fluir libremente
fuente
siempre puede intentar imprimir_r-ing $ _SERVER y buscar
3

Sé que esto podría no ser completamente sobre el tema, pero en mi experiencia, encuentro útil almacenar WWW-ness de la URL actual en una variable.

Editar: Además, vea mi comentario a continuación, para ver a qué se refiere.

Esto es importante al determinar si se deben enviar llamadas Ajax con "www" o sin:

$.ajax("url" : "www.site.com/script.php", ...

$.ajax("url" : "site.com/script.php", ...

Al despachar una llamada Ajax, el nombre de dominio debe coincidir con el de la barra de direcciones del navegador; de lo contrario, tendrá UnError de seguridad no capturado en la consola.

Entonces se me ocurrió esta solución para abordar el problema:

<?php
    substr($_SERVER['SERVER_NAME'], 0, 3) == "www" ? $WWW = true : $WWW = false;

    if ($WWW) {
        /* We have www.example.com */
    } else {
        /* We have example.com */
    }
?>

Luego, en función de si $ WWW es verdadero o falso, ejecute la llamada Ajax adecuada.

Sé que esto puede sonar trivial, pero este es un problema tan común que es fácil de evitar.

InfiniteStack
fuente
OP solicitó explícitamente el dominio, y no el SERVER_NAME .
Sebastian G. Marinescu el
Es cierto, pero en estos días también debe preocuparse por el problema de www.
InfiniteStack
¿Por qué? En JS puedes mirar hacia adentro window.location. En PHP tienes SERVER_NAME.
Sebastian G. Marinescu el
44
SERVER_NAME devuelve "www.site.com" incluso cuando se ingresa "site.com" en la barra de direcciones. Si está utilizando SERVER_NAME en todo su código, inevitablemente se encontrará con el problema de seguridad www / no-www, especialmente cuando se trata de hacer llamadas Ajax. Pero para responder a su pregunta, en la programación avanzada de PHP, a veces PHP necesita generar dinámicamente código que realiza una llamada HTTP al servidor. Si la URL de destino contiene "www" en una página que no lo tiene, generará un error de seguridad.
InfiniteStack el
Ok ok ... Lo leí y tienes razón. Entonces su respuesta podría ser relevante para alguien. Buen trabajo :)
Sebastian G. Marinescu
3

Todos están usando la parse_urlfunción, pero a veces el usuario puede pasar el argumento en un formato diferente.

Para arreglar eso, he creado la función. Mira esto:

function fixDomainName($url='')
{
    $strToLower = strtolower(trim($url));
    $httpPregReplace = preg_replace('/^http:\/\//i', '', $strToLower);
    $httpsPregReplace = preg_replace('/^https:\/\//i', '', $httpPregReplace);
    $wwwPregReplace = preg_replace('/^www\./i', '', $httpsPregReplace);
    $explodeToArray = explode('/', $wwwPregReplace);
    $finalDomainName = trim($explodeToArray[0]);
    return $finalDomainName;
}

Simplemente pase la URL y obtenga el dominio.

Por ejemplo,

echo fixDomainName('https://stackoverflow.com');

devolverá el resultado será

stackoverflow.com

Y en alguna situación:

echo fixDomainName('stackoverflow.com/questions/id/slug');

Y también volverá stackoverflow.com.

Manojkiran.A
fuente
1
$_SERVER['HTTP_HOST'] 

// para obtener el dominio

$protocol=strpos(strtolower($_SERVER['SERVER_PROTOCOL']),'https') === FALSE ? 'http' : 'https';
$domainLink=$protocol.'://'.$_SERVER['HTTP_HOST'];

// dominio con protocolo

$url=$protocol.'://'.$_SERVER['HTTP_HOST'].'?'.$_SERVER['QUERY_STRING'];

// protocolo, dominio, total de queryString ** ¡Como $ _SERVER ['SERVER_NAME'] no es confiable para el alojamiento de múltiples dominios!

Sarkar
fuente
-2

Simplemente intente:

echo apache_request_headers()[3];
Movimiento
fuente