获取客户端IP用什么方式?

在这个灌水盛行的年代,我们必须要对那些心怀不轨,总是想着做点啥坏事的青年们,致以亲切的祝福:最近还好吗,是不是闲的蛋疼。

本博客使用Typecho 程序搭建,添加验证码插件后,垃圾评论还是有不少。隔个5-6天就有20多条,前几天修正了验证码插件当中的一个bug,稍微减缓了一点,不过还是有一些。这里就再对后台 “同一IP发布评论的时间间隔限制为N钟”这个功能动点手脚吧。首先要说明的是,这个功能并不能阻挡这些“灌水青年”的恶劣行为,这是因为基于Typecho程序,这个IP可以伪造,致使上面的设置起不到作用。但是这并不能认为是Typecho的bug,因为当你了解了它的用意之后就会明白。

先来看看这段代码:var/Typecho/Request.php

    /**
     * 设置ip地址
     *
     * @access public
     * @param unknown $ip
     * @return unknown
     */
    public function setIp($ip = NULL)
    {
        switch (true) {
            case NULL !== $this->getServer('HTTP_X_FORWARDED_FOR'):
                $this->_ip = $this->getServer('HTTP_X_FORWARDED_FOR');
                return;
            case NULL !== $this->getServer('HTTP_CLIENT_IP'):
                $this->_ip = $this->getServer('HTTP_CLIENT_IP');
                return;
            case NULL !== $this->getServer('REMOTE_ADDR'):
                $this->_ip = $this->getServer('REMOTE_ADDR');
                return;
            default:
                break;
        }

        $this->_ip = 'unknown';
    }

    /**
     * 获取ip地址
     *
     * @access public
     * @return string
     */
    public function getIp()
    {
        if (NULL === $this->_ip) {
            $this->setIp();
        }

        return $this->_ip;
    }

通过getIp来获取,然后会调用setIp,所以在这里setIp是关键代码。通过上面setIp的代码可以了解到,程序会依次从 $_SERVER['HTTP_X_FORWARDED_FOR'],$_SERVER['HTTP_CLIENT_IP'],$_SERVER['REMOTE_ADDR'] 这上三个变量中获取客户端 IP 。但是在 $_SERVER['HTTP_XXX'] 这种格式的变量是客户端浏览器发送过来的,也就是可以伪造。

那为什么Typecho 程序员会写出这样的代码呢,你要相信他们的聪明才智,这么写是行业通用做法。那究竟作用在哪里呢?当运行Typecho程序的服务器与客户端浏览器之前还有一层代理服务器时,通过 $_SERVER['REMOTE_ADDR'] 获取到的IP不是客户端真正的IP地址,而是这层代理服务器的IP,所以为了兼容这种服务器架构,Typecho程序才这么写。

现在明白了吧,可以根据自己服务器的架构来优化这个代码,以达到防灌水的目的。如果服务器可以直接通过IP访问,那么可以像以下方式修改代码,否则慎重考虑,三思而后行。

    public function setIp($ip = NULL)
    {
        switch (true) {
            case NULL !== $this->getServer('REMOTE_ADDR'):
                $this->_ip = $this->getServer('REMOTE_ADDR');
                return;
            default:
                break;
        }

        $this->_ip = 'unknown';
    }

如果有更好、更简便的方式,请您转告一声。

10
Nov 2013
AUTHOR WiFeng
CATEGORY Web
COMMENTS No Comments

添加新评论 »

   点击刷新验证码