fastapi、flask和tornado对获取请求IP的探索

一、背景

目的是做一个根据请求获取请求者IP的功能,其应用场景包括:限定每次只有一个客户端登录,判断IP是否在白名单内以及根据IP获取位置信息的功能。

二、思路

思路很简单,就是将请求头的Request的内容提取出来,查阅fastapi和flask手册是有相关的方法的,同时还可以利用nginx代理获取更多的IP信息,接下来就尝试一下。

三、实现

1、FastApi

1)代码

此代码要在云服务器上跑,因为在本地跑 本地访问 ip肯定是127.0.0.0,如果是局域网,那么ip就是局域网内的ip

#!/usr/bin/env python
# coding: utf-8
import uvicorn
from fastapi import FastAPI,Request

app = FastAPI()

@app.get("/ip")
async def root(request: Request):
    result={
        "ip":request.client.host,
        "x-real-ip":request.headers.get("X-Real-Ip",""),
        "x-forwarded-for":request.headers.get("x-forwarded-for","")
    }
    return result  

if __name__ == '__main__':
    uvicorn.run("fastapiMain:app", host="0.0.0.0", port=5000, log_level="info", reload=True, debug=True,forwarded_allow_ips ='*')

2)访问结果

无Nginx 无代理
在这里插入图片描述
无Nginx有代理,这里尝试了浏览器的某插件,这里不能写出来,审核不通过。
在这里插入图片描述
有Nginx 无代理
在这里插入图片描述
有Nginx有代理
在这里插入图片描述
分析一下,这里的x-real-ip和x-forwarded-for是通过nginx加进去的,所以无nginx的时候是空值,这里即使用了代理也获取不到真实的ip可能是因为匿名方式的不同,给出一篇博文,大家可以看看。

2、Flask

1)代码

from flask import Flask, request
app = Flask(__name__)

@app.route('/ip')
def index():
    result={
        "ip":request.remote_addr,
        "X-Real-Ip":request.headers.get("X-Real-Ip",""),
        "X-Forwarded-For":request.headers.get("X-Forwarded-For","")
    }
    return result

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True,port=5000)

2)访问结果

和前面的一样,但是值得注意的是,当使用nginx代理的时候,有一个ip显示了127.0.0.1,其一是访问这个ip的方法的不同,其二我用了反向代理,将8080的端口请求代理到127.0.0.1:5000,因此可能会显示127.0.0.0
在这里插入图片描述

3、tronado

1)代码

import tornado.ioloop
import tornado.web

class IndexHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
        self.set_header('Access-Control-Allow-Origin', "*")
        
    @tornado.gen.coroutine#异步处理
    def get(self):
        result={
            "ip":self.request.remote_ip,
            "X-Real-Ip":self.request.headers.get("X-Real-Ip",""),
            "X-Forwarded-For":self.request.headers.get("X-Forwarded-For","")
        }
        self.write(result)

def make_app():
    return tornado.web.Application([
        (r"/ip", IndexHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(5000)
    tornado.ioloop.IOLoop.current().start()

2)访问结果

和flask类似

4、补充Nginx的配置信息

   server{
       listen 8080;
       server_name localhost;
       location /api/{
       rewrite ^/api/(.*)$ /$1 break;
       proxy_pass http://127.0.0.1:5000/;
       proxy_set_header   Host             $host;
       proxy_set_header   X-Real-IP        $remote_addr;
       proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
       proxy_set_header   X-Forwarded-Proto    $scheme;
     }
   }

简单的解释一下,监听8080端口,匹配以/api/开头的路由,并且重写路由,将/api/去掉,将请求给127.0.0.1:5000处理,添加四个属性到请求header
例如我请求http://www.ahutwyc.tech:8080/api/ip,那么就会被代理到http://127.0.0.1:5000/ip,当然这里127.0.0.1就是服务器内部的网络了。

四、总结

理论的东西没搞清楚,所以没法展开说,就代码实现来说是这样的,当然还有很多问题待解决,比如在代理的情况下如何获取真实ip,既然网警可以知道,那么技术上是可以实现的,是否需要原生的数据流才可以呢?或者其他非HTTP协议呢?有待探索,如果有什么问题欢迎大家讨论学习。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖人称王某人的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值