【问题标题】:get_host() vs META['REMOTE_ADDR'] for security reasons出于安全原因,get_host() 与 META['REMOTE_ADDR']
【发布时间】:2013-07-12 05:01:50
【问题描述】:

我正在开发一个 Django 项目,用户将根据他们的位置获得自定义信息。为了做到这一点,我使用他们的 IP 地址来识别他们的国家。为了使数据库中的数据保持一致,我需要确保我有一个准确的 IP。

我了解使用 META 通常使用客户端浏览器发送的标头,但我不知道这是否适用于 REMOTE_ADDR 属性。

TLDR:HttpRequest.get_host()HttpRequest.META['REMOTE_ADDR'] 有什么区别?

【问题讨论】:

    标签: django django-forms django-views


    【解决方案1】:

    HttpRequest.get_host()HttpRequest.META['REMOTE_ADDR'] 之间的区别在于,第一个在以下标头中按优先级降序检查 IP:

    1. HTTP_X_FORWARDED_HOST
    2. HTTP_HOST
    3. SERVER_NAME combined with SERVER_PORT

    而第二个检查标题 REMOTE_ADDR 中的 IP。

    返回的信息类型存在巨大差异:get_host() 将提供托管应用程序的服务器的名称,而不是客户端的 IP。

    更详细的,这里是get_host()的实现:

    def get_host(self):
        """Returns the HTTP host using the environment or request headers."""
        # We try three options, in order of decreasing preference.
        if settings.USE_X_FORWARDED_HOST and (
            'HTTP_X_FORWARDED_HOST' in self.META):
            host = self.META['HTTP_X_FORWARDED_HOST']
        elif 'HTTP_HOST' in self.META:
            host = self.META['HTTP_HOST']
        else:
            # Reconstruct the host using the algorithm from PEP 333.
            host = self.META['SERVER_NAME']
            server_port = str(self.META['SERVER_PORT'])
            if server_port != ('443' if self.is_secure() else '80'):
                host = '%s:%s' % (host, server_port)
    
        allowed_hosts = ['*'] if settings.DEBUG else settings.ALLOWED_HOSTS
        domain, port = split_domain_port(host)
        if domain and validate_host(domain, allowed_hosts):
            return host
        else:
            msg = "Invalid HTTP_HOST header: %r." % host
            if domain:
                msg += "You may need to add %r to ALLOWED_HOSTS." % domain
            raise DisallowedHost(msg)
    

    如果您想检查客户端 IP 地址,这里有一些值得检查的标头(请参阅Getting the client IP address: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, what else could be useful?):

    • REMOTE_ADDR
    • HTTP_X_FORWARDED_FOR
    • HTTP_CLIENT_IP
    • HTTP_X_FORWARDED_FOR 可以是逗号分隔的 IP 列表
    • HTTP_X_FORWARDED
    • HTTP_X_CLUSTER_CLIENT_IP
    • HTTP_FORWARDED_FOR
    • HTTP_FORWARDED

    如果您不知道要选择哪一个(如果不是全部),您可以记录这些标题并随着时间的推移务实地添加新的检查。

    【讨论】:

    • 这真的回答了 OP 的问题吗?我认为这是两者之间的差异
    • 由于对代码的误解,我的原始答案不相关。我希望这个更好。
    • 这很棒。我想这是在 Django 文档中,但我无法很好地并排比较。谢谢=)
    猜你喜欢
    • 2013-06-30
    • 2016-02-07
    • 2019-11-27
    • 1970-01-01
    • 2016-02-04
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多