自引用 URL

发布于 2024-07-13 07:06:28 字数 649 浏览 3 评论 0原文

构建自引用 URL 的最可靠、最通用的方法是什么? 换句话说,我想生成 http://www.site.com[:port] 用户浏览器访问的 URL 部分。 我正在使用在 Apache 下运行的 PHP。

一些复杂性:

  • 依赖 $_SERVER["HTTP_HOST"] 是危险的,因为这似乎直接来自 HTTP 主机头,有人可以伪造。

  • 可能有也可能没有虚拟主机。

  • 可能有一个使用 Apache 的 Port 指令指定的端口,但如果它位于负载平衡器或代理后面,则该端口可能不是用户指定的端口。

  • 端口实际上可能不是 URL 的一部分。 例如,通常会省略 80 和 443。

  • PHP 的 $_SERVER["HTTPS"] 并不总是给出可靠的值,特别是当您位于负载均衡器或代理后面时。

  • Apache 有一个 UseCanonicalName 指令,它会影响 SERVER_NAME 和 SERVER_PORT 环境变量的值。 如果有帮助的话,我们可以假设它已打开。

What's the most reliable, generic way to construct a self-referential URL? In other words, I want to generate the http://www.site.com[:port] portion of the URL that the user's browser is hitting. I'm using PHP running under Apache.

A few complications:

  • Relying on $_SERVER["HTTP_HOST"] is dangerous, because that seems to come straight from the HTTP Host header, which someone can forge.

  • There may or may not be virtual hosts.

  • There may be a port specified using Apache's Port directive, but that might not be the port that the user specified, if it's behind a load-balancer or proxy.

  • The port may not actually be part of the URL. For example, 80 and 443 are usually omitted.

  • PHP's $_SERVER["HTTPS"] doesn't always give a reliable value, especially if you're behind a load-balancer or proxy.

  • Apache has a UseCanonicalName directive, which affects the values of the SERVER_NAME and SERVER_PORT environment variables. We can assume this is turned on, if that helps.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

情绪失控 2024-07-20 07:06:28

我建议确保安全的唯一方法是在站点的某种配置文件中为 url 定义一个常量。 您可以使用 $_SERVER['HTTP_HOST'] 作为默认值生成常量,并在安全性真正重要的部署中替换为硬编码定义。

define('SITE_URL', $_SERVER['HTTP_HOST']);

并根据需要替换:

define('SITE_URL', 'http://foo.bar.com:8080/');

I would suggest that the only way to be sure and to be secure is to define a constant for the url in some kind of config file for the site. You could generate the constant with $_SERVER['HTTP_HOST'] as a default and replace with a hard coded definition on deployments where security really matters.

define('SITE_URL', $_SERVER['HTTP_HOST']);

and replace as needed:

define('SITE_URL', 'http://foo.bar.com:8080/');
难得心□动 2024-07-20 07:06:28

我记得,你想要做这样的事情:

$protocol = 'http';

if ( (!empty($_SERVER['HTTPS'])) || ($_SERVER['HTTPS'] == 'off') ) {
    $protocol = 'https';
    if ($_SERVER['SERVER_PORT'] != 443)
        $port = $_SERVER['SERVER_PORT'];
} else if ($_SERVER['SERVER_PORT'] != 80) {
    $port = $_SERVER['SERVER_PORT'];
}
// Server name is going to be whatever the virtual host name is set to in your configuration
$address = $protocol . '://' . $_SERVER['SERVER_NAME'];
if (!empty($port))
    $address .= ':' . $port
$address .= $_SERVER['REQUEST_URI'];
// Optional, if you want the query string intact
if (!empty($_SERVER['QUERY_STRING']))
    $address .= '?' . $_SERVER['QUERY_STRING'];

我还没有测试过这段代码,因为我目前没有方便的 PHP。

As I recall, you want to do something like this:

$protocol = 'http';

if ( (!empty($_SERVER['HTTPS'])) || ($_SERVER['HTTPS'] == 'off') ) {
    $protocol = 'https';
    if ($_SERVER['SERVER_PORT'] != 443)
        $port = $_SERVER['SERVER_PORT'];
} else if ($_SERVER['SERVER_PORT'] != 80) {
    $port = $_SERVER['SERVER_PORT'];
}
// Server name is going to be whatever the virtual host name is set to in your configuration
$address = $protocol . '://' . $_SERVER['SERVER_NAME'];
if (!empty($port))
    $address .= ':' . $port
$address .= $_SERVER['REQUEST_URI'];
// Optional, if you want the query string intact
if (!empty($_SERVER['QUERY_STRING']))
    $address .= '?' . $_SERVER['QUERY_STRING'];

I haven't tested this code, because I don't have PHP handy at the moment.

末が日狂欢 2024-07-20 07:06:28

最可靠的方法就是自己提供。

该站点应编码为主机名中立,但要了解特殊的配置文件。 该文件不会被放入代码库的源代码管理中,因为它属于网络服务器的配置。 该文件用于设置主机名和其他特定于 Web 服务器的参数等内容。 您可以容纳负载平衡器、更改端口等,因为您是说如果 HTTP 请求命中该代码,那么它可以假设您让它假设的程度。

顺便说一句,这个技巧也有助于开发。 :-)

The most reliable way is to provide it yourself.

The site should be coded to be hostname neutral, but to know about a special configuration file. This file doesn't get put into source control for the codebase because it belongs to the webserver's configuration. The file is used to set things like the hostname and other webserver-specific parameters. You can accomodate load balancers, changing ports, etc, because you're saying if an HTTP request hits that code, then it can assume however much you will let it assume.

This trick also helps development, incidentally. :-)

魂ガ小子 2024-07-20 07:06:28

$_SERVER["HTTP_HOST"] 可能是最好的方法,当然是经过一些验证后。

是的,用户指定了它,因此它不可信,但您可以轻松检测到用户何时用它玩游戏。

$_SERVER["HTTP_HOST"] is probably the best way, after some validation of course.

Yes, the user specifies it and so it cannot be trusted, but you can easily detect when the user is playing games with it.

岁月静好 2024-07-20 07:06:28

验证 $_SERVER['HTTP_HOST'] 是否有效的一种想法是通过 DNS 进行验证。 我在一两种情况下使用过这种方法,没有对速度造成严重后果,而且我相信如果提供了 IP 地址,这种方法会默默地失败。

http://www.php.net/manual/en/function.gethostbyname。 php

伪代码可能是:

define('SITEHOME', in_array(gethostbyname($_SERVER['HTTP_HOST']), array(... valid IP's))) 
? $_SERVER['HTTP_HOST']
: 'default_hostname';

One idea for validating that $_SERVER['HTTP_HOST'] is valid could be to validate it by DNS. I've used this method in one or two cases without serious consequences to speed and I believe this method fails silently if provided a IP address.

http://www.php.net/manual/en/function.gethostbyname.php

Peusudo code might be:

define('SITEHOME', in_array(gethostbyname($_SERVER['HTTP_HOST']), array(... valid IP's))) 
? $_SERVER['HTTP_HOST']
: 'default_hostname';
尹雨沫 2024-07-20 07:06:28

为什么{如果您希望用户继续使用他们正在使用的 http:///host:port/您希望生成完整的网址}
您可以使用相对网址,而不是

在页面上说 http://xxx:yy/zzz/fff/< /a>

你可以使用

../graphics/whatever.jpg
{从当前目录返回一个目录并获取 http://xxx:yy/zzz/graphics/随便.jpg


/zzz/graphics/whatever.jpg
{转到站点根目录并按指定的方式处理目录}

这些都避免提及主机:端口部分并从当前使用的部分继承它

why {if you wish the user to continue using http:///host:port/ that they are on do you wish to generate full urls}
whan you can use relative urls instead of either

say on page http://xxx:yy/zzz/fff/

you culd use either

../graphics/whatever.jpg
{to go back one directory from current and get http://xxx:yy/zzz/graphics/whatever.jpg

or
/zzz/graphics/whatever.jpg
{to goto site root and work up the directories as specified}

these both avoid mentioning the host:port part and inherit it from the one currently in use

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文