整个架构是:
用户访问域名 =》 cloudflare =》 nginx =》 django
默认情况, 通过 request.META.get('REMOTE_ADDR')
获取到的是 cloudflare 的 ip(由于我用了docker,所以我拿到的似乎是docker内部ip), 而不是用户真实ip。
request.META.get('HTTP_X_REAL_IP')
拿到的, 也不是真实ip
花了不少时间在网上搜, 各种花里胡哨的办法 都尝试了, 比如:
1、修改 nginx 把 cloudflare 的ip 存到 nginx 配置
2、比如 map 映射
3、。。。。
都感觉太繁琐,而且似乎也不行, 最后发现, cloudflare 似乎 默认就给设置了 一个 HTTP_CF_CONNECTING_IP
这个就是真实ip
通过 request.META.get('HTTP_CF_CONNECTING_IP') 就可以拿到 用户真实ip了。
只需要一个步骤:
request.META.get('HTTP_CF_CONNECTING_IP')
def get_real_ip(request):
"""
获取用户真实ip, 支持阿里云cdn,cloudflare cdn
"""
if 'HTTP_ALI_CDN_REAL_IP' in request.META: # 阿里云
remote_ip_tmp = request.META.get('HTTP_ALI_CDN_REAL_IP')
elif 'HTTP_CF_CONNECTING_IP' in request.META: # cloudflare
remote_ip_tmp = request.META.get('HTTP_CF_CONNECTING_IP')
elif 'X-Forwarded-For' in request.META:
remote_ip_tmp = request.META.get('X-Forwarded-For').split(',')[0]
else:
remote_ip_tmp = request.META.get('REMOTE_ADDR', None)
return remote_ip_tmp
cloudflare 还有其他一个 http的头:
'HTTP_CF_RAY': 'xxxxxxx-LHR', // 不知道做什么的
'HTTP_CF_IPCOUNTRY': 'CN', // 国家?
'HTTP_CF_VISITOR': '{"scheme":"https"}', // 不知道做什么的
'HTTP_CF_CONNECTING_IP': 'xxx.xx.xx.xx', // 真实ip
cf这些头的 说明文档: https://developers.cloudflare.com/fundamentals/reference/http-request-headers/