Obtenir le domaine actuel

140

J'ai mon site sur le serveur

http://www.myserver.uk.com

Pour cela j'ai deux domaines,

http://one.com

et

http://two.com

Je voudrais obtenir avec le domaine actuel PHP, mais si j'utilise $_SERVER['HTTP_HOST']alors ceci me montre

myserver.uk.com

au lieu de:

one.com or two.com

Comment puis-je obtenir le domaine, pas le nom du serveur?

J'ai la version 5.2 de PHP.

Tony Evyght
la source
Vous ne pouvez obtenir que l'URL principale. Lequel est primaire parmi ces trois?
Code Spy
2
Exactement comment vos deux domaines «redirigent» les requêtes vers votre serveur?
xiaofeng.li
1
@infgeoax probablement un cadre ...
CodeCaster
primaire est myserver.uk.com. alors comment puis-je obtenir le nom de domaine actuel? Si j'ouvre le site avec l'adresse one.com, je voudrais obtenir one.com au lieu de myserver.uk.com
Tony Evyght
@TonyEvyght c'est le point d'infgeoax et j'essaie de faire, vous devriez obtenir le nom d'hôte avec lequel vous vous connectez $_SERVER['HTTP_HOST']. Si les sites one.comet two.com"redirigent" en utilisant un cadre (i), la page elle-même provient toujours de myserver.uk.com, donc vous n'obtiendrez pas le vrai domaine. À quoi sert la source HTML one.com?
CodeCaster

Réponses:

175

Essayez d'utiliser ceci: $_SERVER['SERVER_NAME']

Ou analyser

$_SERVER['REQUEST_URI']

apache_request_headers ()

une moitié
la source
23
-1: Avec cette seule réponse, je ne sais pas exactement ce que font les différentes suggestions que je regarde. Bien sûr, cela me donne un point sur lequel continuer à chercher, mais en soi ce n'est vraiment pas une bonne réponse ...
Jasper
4
juste print_r (apache_request_headers ()) et vous comprendrez tout :)
demi
2
@SarahLewis HTTP_X_ORIGINAL_HOSTpeut être modifié par l'utilisateur et ne peut pas faire confiance. Ce n'est peut-être pas toujours un problème, mais c'est quelque chose dont il faut être conscient.
wp-overwatch.com
64

La meilleure utilisation serait

echo $_SERVER['HTTP_HOST'];

Et il peut être utilisé comme ceci:

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

Ce code ci-dessous est un bon moyen de voir toutes les variables de $ _SERVER dans une sortie HTML structurée avec vos mots-clés mis en surbrillance qui s'arrête directement après l'exécution. Comme j'oublie parfois lequel utiliser moi-même - je pense que cela peut être astucieux.

<?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
la source
39

L'utilisation de $_SERVER['HTTP_HOST']me (sous-domaine.) Maindomain.extension. Cela me semble être la solution la plus simple.

Si vous «redirigez» réellement via un iFrame, vous pouvez ajouter un paramètre GET qui indique le domaine.

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

Et puis vous pouvez définir une variable de session qui persiste ces données dans toute votre application.

Raz0rwire
la source
1
surtout, il comprend le numéro de port afin que je n'ai pas besoin de le concaténer par la suite. phpinfo suggéré par bsdnoobz m'aide cependant à trouver la bonne solution.
30

Le seul moyen sûr de le faire

Toutes les autres réponses de cette page ont des implications en matière de sécurité dont vous devez être conscient.

La seule méthode sécurisée garantie pour récupérer le domaine actuel est de 𝓼𝓽𝓸𝓻𝓮 𝓲𝓽 𝓲𝓷 𝓪 𝓼𝓮𝓬𝓾𝓻𝓮 𝓵𝓸𝓬𝓪𝓽𝓲𝓸𝓷 𝔂𝓸𝓾𝓻𝓼𝓮𝓵𝓯.

La plupart des frameworks s'occupent de stocker le domaine pour vous, vous voudrez donc consulter la documentation de votre framework particulier. Si vous n'utilisez pas de framework, envisagez de stocker le domaine dans l'un des endroits suivants:

+ ------------------------------------------------- --- + ----------------------------------- +
 | Méthodes sécurisées de stockage du domaine | Utilisé par |
+ ------------------------------------------------- --- + ----------------------------------- +
 | Un fichier de configuration | Joomla, Drupal / Symfony |
 | La base de données | WordPress |
 | Une variable environnementale | Laravel |
 | Un registre de services | DNS Kubernetes |
+ ------------------------------------------------- --- + ----------------------------------- +


Vous pouvez utiliser les éléments suivants ... mais ils ne sont pas sécurisés

Les pirates peuvent faire en sorte que ces variables affichent le domaine de leur choix. Cela peut entraîner un empoisonnement du cache et des attaques de phishing à peine perceptibles.

$_SERVER['HTTP_HOST']

Cela obtient le domaine à partir des en-têtes de requête qui sont ouverts à la manipulation par les pirates . Même avec:

$_SERVER['SERVER_NAME']

Celui-ci peut être amélioré si le paramètre Apache usecanonicalname est désactivé; dans ce cas, $_SERVER['SERVER_NAME']il ne sera plus autorisé à être rempli avec des valeurs arbitraires et sera sécurisé. Cependant, ce n'est pas le cas par défaut et n'est pas courant dans une configuration.


Dans les systèmes populaires

Voici comment vous pouvez obtenir le domaine actuel dans les frameworks / systèmes suivants:

WordPress

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

Si vous construisez une URL dans WordPress, utilisez simplement home_url ou site_url , ou l'une des autres fonctions URL .

Laravel

request()->getHost()

La request()->getHostfonction est héritée de Symfony et est sécurisée depuis la mise à jour de la CVE-2013-4752 2013 .

Drupal

Le programme d'installation ne prend pas encore soin de rendre cela sécurisé ( problème # 2404259 ). Mais dans Drupal 8, il existe une documentation que vous pouvez suivre dans Paramètres d'hôte de confiance pour sécuriser votre installation Drupal, après quoi les éléments suivants peuvent être utilisés:

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

Autres cadres

N'hésitez pas à modifier cette réponse pour inclure comment obtenir le domaine actuel dans votre cadre préféré. Ce faisant, veuillez inclure un lien vers le code source pertinent ou vers tout autre élément qui m'aiderait à vérifier que le framework fait les choses en toute sécurité.




Addenda

Exemples d'exploitation:

  1. Un empoisonnement du cache peut se produire si un botnet demande en permanence une page en utilisant le mauvais en-tête d'hôtes. Le code HTML résultant inclura alors des liens vers le site Web des attaquants où ils peuvent hameçonner vos utilisateurs. Au début, les liens malveillants ne seront renvoyés qu'au pirate, mais si le pirate fait suffisamment de requêtes, la version malveillante de la page se retrouvera dans votre cache où elle sera distribuée à d'autres utilisateurs.

  2. Une attaque de phishing peut se produire si vous stockez des liens dans la base de données en fonction de l'en-tête hosts. Par exemple, supposons que vous stockiez l'URL absolue des profils d'un utilisateur sur un forum. En utilisant le mauvais en-tête, un pirate informatique peut amener quiconque clique sur le lien de son profil à se voir envoyer un site de phishing.

  3. Un empoisonnement de réinitialisation de mot de passe peut se produire si un pirate informatique utilise un en-tête d'hôtes malveillants lorsqu'il remplit le formulaire de réinitialisation de mot de passe pour un autre utilisateur. Cet utilisateur recevra alors un e-mail contenant un lien de réinitialisation de mot de passe menant à un site de phishing.

  4. Voici d' autres exemples malveillants

Mises en garde et remarques supplémentaires:

  • Lorsque usecanonicalname est désactivé, le $_SERVER['SERVER_NAME']est rempli avec le même en-tête $_SERVER['HTTP_HOST']que celui utilisé de toute façon (plus le port). Il s'agit de la configuration par défaut d'Apache. Si vous ou devops activez cela, alors tout va bien - ish - mais voulez-vous vraiment compter sur une équipe distincte, ou vous-même trois ans dans le futur, pour conserver ce qui semble être une configuration mineure à un non -valeur par défaut? Même si cela sécurise les choses, je vous déconseille de me fier à cette configuration.
  • Redhat, cependant, active l'utilisation de Canon par défaut [ source ].
  • Si serverAlias est utilisé dans l'entrée des hôtes virtuels et que le domaine avec alias est demandé, $_SERVER['SERVER_NAME']ne renverra pas le domaine actuel, mais renverra la valeur de la directive serverName.
  • Si le nom du serveur ne peut pas être résolu, la commande hostname du système d'exploitation est utilisée à sa place [source] .
  • Si l'en-tête de l'hôte est omis, le serveur se comportera comme si usecanonical était sur [source] .
  • Enfin, j'ai juste essayé d'exploiter cela sur mon serveur local et je n'ai pas pu usurper l'en-tête d'hôtes. Je ne sais pas s'il y avait une mise à jour d'Apache qui a résolu ce problème, ou si je faisais simplement quelque chose de mal. Quoi qu'il en soit, cet en-tête serait toujours exploitable dans les environnements où les hôtes virtuels ne sont pas utilisés.

Little Rant:

     Cette question a reçu des centaines de milliers de vues sans une seule mention des problèmes de sécurité à portée de main! Cela ne devrait pas être le cas, mais ce n'est pas parce qu'une réponse Stack Overflow est populaire, cela ne signifie pas qu'elle est sécurisée.



wp-overwatch.com
la source
1
Vous voudrez peut-être mentionner la différence entre home_url et site_url. wordpress.stackexchange.com/a/50605/13
Volomike
1
+1 pour les utilisateurs de wordpress. Bon si vous devez examiner s'il est installé dans le sous-répertoire, mais notez que parse_url key: $urlparts['path']n'est pas défini s'il est installé dans le répertoire racine du domaine. Else $urlparts['path']renvoie le sous-répertoire.
Jonas Lundman
9

Essayez $_SERVER['SERVER_NAME'].

Astuces: Créez un fichier PHP qui appelle la fonction phpinfo()et consultez la section "Variables PHP". Il y a un tas de variables utiles auxquelles nous ne pensons jamais.

sans flux
la source
vous pouvez toujours essayer print_r-ing le $ _SERVER et rechercher
3

Je sais que ce n'est peut-être pas entièrement sur le sujet, mais d'après mon expérience, je trouve utile de stocker le WWW-ness de l'URL actuelle dans une variable.

Edit: En outre, veuillez consulter mon commentaire ci-dessous, pour voir à quoi cela aboutit.

Ceci est important pour déterminer s'il faut distribuer les appels Ajax avec "www" ou sans:

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

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

Lors de l'envoi d'un appel Ajax, le nom de domaine doit correspondre à celui de dans la barre d'adresse du navigateur, sinon vous aurez Uncaught SecurityError dans la console.

J'ai donc proposé cette solution pour résoudre le problème:

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

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

Ensuite, selon que $ WWW est vrai ou faux, exécutez l'appel Ajax approprié.

Je sais que cela peut sembler trivial, mais c'est un problème tellement courant qu'il est facile de trébucher.

InfiniteStack
la source
OP a explicitement demandé le domaine, et non le SERVER_NAME .
Sebastian G.Marinescu
C'est vrai, mais ces jours-ci, vous devez également vous soucier du problème www.
InfiniteStack
Pourquoi? Dans JS, vous pouvez regarder window.location. En PHP, vous avez SERVER_NAME.
Sebastian G.Marinescu
4
SERVER_NAME renvoie «www.site.com» même lorsque «site.com» est entré dans la barre d'adresse. Si vous utilisez SERVER_NAME dans tout votre code, vous serez inévitablement confronté au problème de sécurité www / no-www, en particulier lorsqu'il s'agit de passer des appels Ajax. Mais pour répondre à votre question, dans la programmation PHP avancée, PHP a parfois besoin de générer dynamiquement du code qui effectue un appel HTTP vers le serveur. Si l'URL cible contient "www" sur une page qui n'en contient pas, une erreur de sécurité sera générée.
InfiniteStack
Ok ok ... J'ai lu et tu as raison. Votre réponse pourrait donc être pertinente pour quelqu'un. Bon travail :)
Sebastian G.Marinescu
3

Tout le monde utilise la parse_urlfonction, mais parfois l'utilisateur peut transmettre l'argumet dans un format différent.

Pour résoudre ce problème, j'ai créé la fonction. Regarde ça:

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;
}

Passez simplement l'URL et obtenez le domaine.

Par exemple,

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

retournera le résultat sera

stackoverflow.com

Et dans certaines situations:

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

Et il reviendra également stackoverflow.com.

Manojkiran.A
la source
1
$_SERVER['HTTP_HOST'] 

// pour obtenir le domaine

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

// domaine avec protocole

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

// protocole, domaine, queryString total ** Comme le $ _SERVER ['SERVER_NAME'] n'est pas fiable pour l'hébergement multi-domaines!

Sarkar
la source
-2

Essayez simplement:

echo apache_request_headers()[3];
Mouvement
la source