php 获取当前域

xe55xuns  于 2023-02-03  发布在  PHP
关注(0)|答案(9)|浏览(102)

我在服务器http://www.myserver.uk.com上有我的站点。
在此服务器上我有两个域:

one.com and two.com

我想使用PHP获取当前域,但如果我使用$_SERVER['HTTP_HOST'],它会显示给我

myserver.uk.com

而不是:

one.com or two.com

我怎样才能得到域名,而不是服务器名?

oknrviil

oknrviil1#

请尝试使用此:

$_SERVER['SERVER_NAME']

或解析:

$_SERVER['REQUEST_URI']

参考:* apache_request_headers() *

b4qexyjb

b4qexyjb2#

最好的用途是

echo $_SERVER['HTTP_HOST'];

它可以这样使用:

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

下面的代码是一个很好的方法,可以在结构化的HTML输出中查看$_ SERVER中的所有变量,并突出显示您的关键字,执行后会立即停止。因为我有时会忘记使用哪一个-我认为这可能是一个很好的方法。

<?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();
?>
ahy6op9u

ahy6op9u3#

唯一安全的方法是
检索当前域的唯一有保证的安全方法是自己将其存储在安全位置。
大多数框架都会为你保存域,所以你需要参考特定框架的文档。如果你没有使用框架,可以考虑将域保存在以下位置之一:
| 存储域的安全方法  使用者| Used By |
| - ------|- ------|
| 配置文件 JoomlaDrupal/Symfony| Joomla , Drupal / Symfony |
| 该数据库 |WordPress|
| 环境变量|Laravel |
| 服务注册表 Kubernetes域名系统| Kubernetes DNS |

以下项可以工作...但不安全

黑客可以让以下变量输出他们想要的任何域。这可能导致缓存中毒和几乎不明显的网络钓鱼攻击。

$_SERVER['HTTP_HOST']

这将从请求标头(open to manipulation by hackers)获取域。与相同:

$_SERVER['SERVER_NAME']

如果关闭Apache设置usecanonicalname,这个问题会变得更好;在这种情况下,$_SERVER['SERVER_NAME']将不再被允许填充任意值,并且是安全的。但是,这不是默认设置,也不是常见的设置。
在流行的系统中
下面是如何在以下框架/系统中获取当前域:

    • 文字出版社**
$urlparts = parse_url(home_url());
$domain = $urlparts['host'];

如果你在WordPress中构造一个URL,只需使用home_urlsite_url,或者other URL functions中的任何一个。

    • 拉腊维尔**
request()->getHost()

request()->getHost函数继承自Symfony,自2013 CVE-2013-4752补丁以来一直是安全的。

    • 德鲁帕尔**

安装程序还没有确保这个安全(issue #2404259),但是在Drupal 8中有一些文档,你可以在Trusted Host Settings中遵循这些文档来保护你的Drupal安装,之后可以使用以下方法:

\Drupal::request()->getHost();
    • 其他框架**

您可以随意编辑此答案,以包括如何在您喜欢的框架中获取当前域。在这样做时,请包括相关源代码的链接或任何其他有助于验证框架是否安全运行的链接。

附录

剥削示例:
1.如果僵尸网络不断使用错误的主机标头请求页面,则会发生缓存中毒。生成的HTML将包含指向攻击者网站的链接,攻击者可以在该网站上对您的用户进行网络钓鱼。最初,恶意链接只会被发送回黑客,但如果黑客执行了足够多的请求,恶意版本的页面将最终进入您的缓存,并分发给其他用户。
1.如果您基于主机标头在数据库中存储链接,则可能发生网络钓鱼攻击。例如,假设您存储了论坛上用户配置文件的绝对URL。通过使用错误的标头,黑客可以让任何单击其配置文件链接的人接收网络钓鱼站点。
1.如果黑客在为其他用户填写密码重置表单时使用恶意主机标头,则可能发生密码重置中毒。该用户随后将收到一封包含密码重置链接的电子邮件,该链接指向钓鱼网站。另一种更复杂的形式是让电子邮件退回并重新发送到黑客的SMTP服务器(for example CVE-2017-8295.),从而使用户无需执行任何操作
1.以下是一些more malicious examples
附加警告和注解:

  • 当usecanonicalname关闭时,$_SERVER['SERVER_NAME']将使用与$_SERVER['HTTP_HOST']本来使用的相同的头填充(加上端口)。这是Apache的默认设置。如果你或DevOps打开这个设置,那么你就可以了--也许--但是你真的想依赖一个单独的团队,或者三年后的你自己,以保持什么似乎是一个次要的配置在一个非默认值?即使这使事情安全,我会警告不要依赖于这个设置。
  • 不过,Red Hat默认情况下会打开usecanonical [source]。
  • 如果虚拟主机条目中使用了serverAlias,并且请求了别名域,则$_SERVER['SERVER_NAME']不会返回当前域,但会返回serverName指令的值。
  • 如果无法解析serverName,则使用操作系统的hostname命令代替它[source]。
  • 如果主机头被省略,服务器的行为就像usecanonical在[source]上一样。
  • 最后,我尝试在本地服务器上利用此漏洞,但无法欺骗hosts标头。我不确定Apache是否有更新解决了此问题,或者我只是做错了什么。无论如何,在不使用虚拟主机的环境中,此标头仍然可以被利用。

一点咆哮:
这个问题收到了成千上万的意见,而没有一个提到安全问题!它不应该是这样的,但只是因为堆栈溢出的答案是流行的,这并不意味着它是安全的。

btqmn9zl

btqmn9zl4#

使用$_SERVER['HTTP_HOST']可以得到(subdomain.)maindomain.extension,这似乎是最简单的解决方案。
如果您实际上是通过一个iFrame“重定向”,您可以添加一个GET参数来说明域。

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

然后,您可以设置一个会话变量,使该数据在整个应用程序中持久化。

ifsvaxew

ifsvaxew5#

试试$_SERVER['SERVER_NAME']
小贴士:创建一个调用函数phpinfo()的PHP文件,并查看"PHP变量"部分,其中有很多我们从未想到过的有用变量。

gev0vcfq

gev0vcfq6#

要获取域:

$_SERVER['HTTP_HOST']

具有协议的域:

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

协议、域和查询字符串总数:

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

**因为$_SERVER ['SERVER_NAME']对于多域托管不可靠!

ivqmmu1c

ivqmmu1c7#

我知道这可能不完全是这个主题,但是根据我的经验,我发现将当前URL的WWW属性存储在变量中是有用的。
此外,请看我下面的评论,看看这是什么意思。
这在确定是否使用“www”分派 AJAX 调用时非常重要:

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

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

在调度 AJAX 调用时,域名必须与浏览器地址栏中的域名匹配,否则控制台中会出现Uncatched SecurityError
所以我想出了这个解决方案来解决这个问题:

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

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

然后,根据$WWW是true还是false运行适当的 AJAX 调用。
我知道这听起来可能微不足道,但这是一个很容易被绊倒的常见问题。

ua4mk5z4

ua4mk5z48#

每个人都在使用parse_url函数,但有时用户可能会以不同的格式传递参数。
为了解决这个问题,我创建了一个函数。

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

只需传递URL并获取域。
例如,

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

将返回:

stackoverflow.com

在某些情况下:

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

它还将返回stackoverflow.com

vfwfrxfs

vfwfrxfs9#

这个快速和肮脏的工程对我来说。
无论你用哪种方式获取包含你想要提取的域的字符串,例如使用超级全局变量-$_SERVER ['SERVER_NAME']-或者,在Drupal中:global $base_url,regex是你的好朋友:

global $base_url;
preg_match("/\w+\.\w+$/", $base_url, $matches);
$domain = $matches[0];

当然,我在示例中使用的特定正则表达式字符串只会捕获$base_url字符串的最后两个组成部分,但是您可以根据需要添加任意多个“\w+.”,希望它会有所帮助。

相关问题