获取用户真实IP

  • app配置,没有使用nginx/cdn等反向代理时需要自己获取客户端ip
app.with_state(app_state).into_make_service_with_connect_info::<SocketAddr>()
  • 通用获取客户端真实ip提取器,需要反响代理配置好请求头
nginx常规配置,cdn一般默认都是这种
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
pub struct Ip(IpAddr);

/// 创建remote ip提取器
#[async_trait]
impl<S> FromRequestParts<S> for Ip
    where
        ConnectionPool: FromRef<S>,
        S: Send + Sync,
{
    type Rejection = (StatusCode, String);

    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
        match parts.headers.get("x-forwarded-for") {
            Some(val) => {
                let ipstr = val.to_str().unwrap().split(", ").collect::<Vec<&str>>();// .strip_suffix(", ").unwrap();
                debug!("remote ipstr: {:?}",ipstr);
                let ip: IpAddr = ipstr[0].parse().unwrap();
                Ok(Ip(ip))
            }
            None => {
                let ext=&parts.extensions;
                let ip = parts.extensions.get::<ConnectInfo<SocketAddr>>().unwrap();
                Ok(Ip(ip.0.ip()))
            }
        }
    }
}

//测试获取ip
 pub async fn getip(ip:Ip)->Html<String>{
    Html(ip.0.to_string())
}