使用golang http包时如何限制客户端IP地址

2023-12-24

我正在使用 golanghttp包裹。服务器如何限制客户端IP地址?

func (s *Worker) Run(c chan error) {
    apiMux := http.NewServeMux()
    apiMux.HandleFunc("/test", s.test)
    apiMux.HandleFunc("/block/create", s.CreateBlock)
    apiMux.HandleFunc("/block/delete", s.DeleteBlock)

    apiServer := &http.Server{
        Addr:    "0.0.0.0:" + strconv.Itoa(s.ListenPort),
        Handler: apiMux,
    }

    go func() {
        log.Println("Worker listening on " + apiServer.Addr)
        c <- apiServer.ListenAndServe()
    }()
}

您需要做两件事:一是使用中间件处理程序包装您的多路复用器,该中间件处理程序会预处理您的请求并验证 IP。另一个是获取用户的真实 IP,如果您位于防火墙或负载均衡器后面(导致地址始终是 LB 的地址),或者您的用户位于代理后面,这一点很重要。

至于包装您的多路复用器,非常简单:

apiServer := &http.Server{
    Addr:    "0.0.0.0:8080",
    Handler: http.HandlerFunc( func(w http.ResponseWriter, req *http.Request) {
        // get the real IP of the user, see below
        addr := getRealAddr(req)

       // the actual vaildation - replace with whatever you want
       if (addr != "1.2.3.4") {
            http.Error(w, "Blocked", 401)
            return
        }
        // pass the request to the mux
        apiMux.ServeHTTP(w,req)
    }),
}

我附上getRealAddr函数来自一个实际项目,我在其中做了这样的事情:

func getRealAddr(r *http.Request)  string {

    remoteIP := ""
    // the default is the originating ip. but we try to find better options because this is almost
    // never the right IP
    if parts := strings.Split(r.RemoteAddr, ":"); len(parts) == 2 {
        remoteIP = parts[0]
    }
    // If we have a forwarded-for header, take the address from there
    if xff := strings.Trim(r.Header.Get("X-Forwarded-For"), ","); len(xff) > 0 {
        addrs := strings.Split(xff, ",")
        lastFwd := addrs[len(addrs)-1]
        if ip := net.ParseIP(lastFwd); ip != nil {
            remoteIP = ip.String()
        }
    // parse X-Real-Ip header
    } else if xri := r.Header.Get("X-Real-Ip"); len(xri) > 0 {
        if ip := net.ParseIP(xri); ip != nil {
            remoteIP = ip.String()
        }
    }

    return remoteIP

}

至于过滤,它可以基于一组 ip 或 CIDR 范围,当然这取决于您。

如果您感兴趣,上面的代码来自我编写和使用的一个名为 Vertex 的 API 构建工具包,该工具包内置了以下代码:https://github.com/EverythingMe/vertex https://github.com/EverythingMe/vertex

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用golang http包时如何限制客户端IP地址 的相关文章

随机推荐

  • 接收 Android Google Play 音乐广播两次

    我希望你今天过得愉快 让我们进入正题 在我的清单文件中 我添加了一个像这样的接收器
  • 为什么在定义结构时使用不同的标识符?

    考虑这段代码 typedef struct Node Node struct Node struct Node node or this typedef struct Node struct Node node Node 有什么理由不将它们
  • netcdf4 提取经纬度子集

    我想提取一个相当大的 netcdf 文件的空间子集 从循环遍历 netcdf 文件并运行计算 Python 或 R https stackoverflow com questions 18665078 loop through netcdf
  • 如何将 StrLn 放入 Data.ByteString.Internal.ByteString?

    我正在学习 Haskell 并决定尝试编写一些小型测试程序来习惯 Haskell 代码和使用模块 目前 我正在尝试使用第一个参数来使用 Cypto PasswordStore 创建密码哈希 为了测试我的程序 我尝试从第一个参数创建一个散列
  • 将列添加到数据库 - 如何更新 dbml 文件?

    有没有一种方法可以刷新 dbml 文件 还是必须删除它并生成一个全新的文件 据我所知 设计器中没有内置功能可以使用数据库中的更改来更新表 有第三方工具 http www huagati com dbmltools http www huag
  • 跳过列表,它们真的像 Pugh 论文声称的那样好吗?

    我正在尝试使用最小的额外内存开销来实现一个与 BST 一样好的跳过列表 目前即使不考虑任何内存限制 我的 SkipList 实现的性能也与非常幼稚的平衡 BST 实现相去甚远 可以这么说 手工制作的 BTS 作为参考 我使用 William
  • Domain=NSURLErrorDomain Code=-1021“请求正文流已耗尽”

    我收到 NSURLErrorDomain Code 1021 请求正文流已耗尽 NSLocalizedDescription 请求正文流耗尽 NSUnderlyingError 0x2088c080 请求正文流耗尽 上传多张大尺寸图片时会出
  • 使用animateTransform时如何指定x-y旋转点?

    我想使用 animateTransform 连续旋转 SVG 图像 那么我们开始吧
  • 使用 c# webrequest 与 asp.net mvc 3 网站交互

    我通过这些操作创建了一个带有家庭控制器的简单 mvc3 站点 public JsonResult Param string id string upper String Concat id ff return Json upper publ
  • Hibernate Criteria 按特定状态排序

    你好 在数据库中 我们有一个 PRSN ADDRESS 表 其中包含许多地址 用户会在网格中看到这些地址 要求是首先显示与该用户的状态关联的地址 然后显示所有其他状态 例如 假设该表有 10 条记录 其中 5 个地址的州为马里兰州 2 个来
  • Visual Basic 将数据作为 json 对象发送到 api

    美好的一天 我尝试将数据作为 json 对象发送到 api Content Type application json Authorization Bearer ACCESS TOKEN d datetime 2021 02 21 14 0
  • 从 WebAPI 控制器获取声明 - JWT 令牌,

    我在 ASP NET Core 中构建了一个使用 JWT 承载身份验证的应用程序 进行身份验证时 我定义了一些自定义声明 我需要在另一个 WebAPI 控制器中读取这些声明才能执行某些操作 有什么想法我怎样才能实现这一目标 这就是我的代码的
  • .net webapi HttpGet 与 HttpPost。为什么使用 HttpGet?

    为什么在WebApi框架中使用HttpGet而不是HttpPost 我很清楚 Post 或 Get 类型之间的区别 一个是通过 url 另一个不是 作为基本理解 但我也知道主要区别 可以在服务器上编辑 是 Post 对发送到服务器的数据大小
  • 如何在 HSQLDB GUI 中执行多个命令?

    我想从 GUI 执行许多命令 我想做很多这样的小组 但我无法让一个小组工作 我想我需要以某种方式强制他们之间的提交 但我不知道如何做到这一点 如果我按顺序单独执行这些命令中的每一个 一切都会按预期进行 我正在使用EPSG dat来自 Geo
  • Google Cloud Vision 的 Advanced_ocr_options[] 是什么?

    我正在尝试查找有关的任何信息advanced ocr options under of ImageContext https cloud google com vision docs reference rest v1 ImageConte
  • uWSGI根据环境变量设置配置

    请帮助我理解uWSGI配置逻辑 我有一个环境变量ENVIRONMENT 假设它的值可以是dev or prod 我想根据以下值设置配置选项ENVIRONMENT always executes print statement doesn t
  • 重塑数组中的数组

    我有一个由 40 个数组组成的数组 每个数组都有 1x150 的形状 有没有办法重塑数组 以便我有 40 个 3x50 数组的数组 我不确定是否有一种方法可以使用 np reshape 并在一行中完成 是吗 这真的是一个arraynp ar
  • Qt 中的 QPointer、QSharedPointer 和 QWeakPointer 类有什么区别?

    我从 Qt 文档中读到了有关QPointer QSharedPointer and QWeakPointer类 它说 QPointer是一个模板类 它为 Qt 对象提供受保护的指针 其行为类似于普通的 C 指针 只不过当引用的对象被销毁并且
  • 如何限制正则表达式捕获组?

    我不明白如何限制捕获组 如果我有这样的正则表达式 w 2 s w 2 4 15 我认为这会捕获任何字符串 正好两个字 每个单词至少 2 个字符长 并且整个字符串不超过 15 个字符 但是我的捕获组的限制不起作用 我可以限制捕获组吗 附言 我
  • 使用golang http包时如何限制客户端IP地址

    我正在使用 golanghttp包裹 服务器如何限制客户端IP地址 func s Worker Run c chan error apiMux http NewServeMux apiMux HandleFunc test s test a