自引用URL

时间:2009-01-28 21:33:24

标签: php apache http cgi

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

一些并发症:

  • 依赖于$ _SERVER [“HTTP_HOST”]是危险的,因为这似乎直接来自HTTP Host标头,有人可以伪造。

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

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

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

  • PHP的$ _SERVER [“HTTPS”]并不总是提供可靠的值,特别是如果您在负载均衡器或代理之后。

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

6 个答案:

答案 0 :(得分:2)

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

$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方便。

答案 1 :(得分:2)

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

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

并根据需要进行更换:

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

答案 2 :(得分:1)

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

该站点应编码为主机名中性,但要了解特殊配置文件。此文件不会被放入代码库的源代码管理中,因为它属于Web服务器的配置。该文件用于设置主机名和其他特定于Web服务器的参数。您可以容纳负载均衡器,更改端口等,因为您说的是HTTP请求是否会触及该代码,然后它可以假设您会让它假设多少。

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

答案 3 :(得分:0)

在经过一些验证之后,

$ _ SERVER [“HTTP_HOST”]可能是最好的方法。

是的,用户指定它并因此无法信任,但您可以轻松检测用户何时使用它进行游戏。

答案 4 :(得分:0)

验证$ _SERVER ['HTTP_HOST']有效的一个想法可能是通过DNS验证它。我在一两个案例中使用过这种方法而没有对速度造成严重后果,我相信如果提供IP地址,这种方法会无声地失败。

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

Peusudo代码可能是:

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

答案 5 :(得分:0)

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

在页面http://xxx:yy/zzz/fff/

上说

你闷闷不乐地使用

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

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

这两个都避免提及host:port部分并从当前正在使用的部分继承它