- 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())
}