2013-07-14 33 views
3

我正在开发一个Django项目,其中用户将根据其位置为其提供自定义信息。为了做到这一点,我使用他们的IP地址来识别他们的国家。为了保持数据库中的数据一致,我需要确保我有一个准确的IP。出于安全原因,get_host()与META ['REMOTE_ADDR']

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

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

回答

3

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

的列表。如果你不知道该选哪一个(如果不是全部),你可以记录这些头文件并实时地添加新的检查。

+0

这是否真的回答OP的问题?我认为这是两者之间的差异 – karthikr

+0

由于对代码的误解,我的原始答案并不相关。我希望这个更好。 –

+0

这太好了。我想这是在Django的文档中,但我无法找到一个好的并排比较。谢谢=) – dirtshell

相关问题