Golang HTTP请求拦截器实现

如何在Golang中实现HTTP请求拦截器?想对请求进行统一处理,比如添加请求头、记录日志或者验证权限,但不太清楚具体的实现方式。能否提供一个完整的示例代码,说明如何注册拦截器以及在请求处理流程中的执行顺序?最好能解释下中间件和拦截器的区别。

2 回复

在Golang中实现HTTP请求拦截器,可以通过中间件模式实现。以下是核心实现步骤:

  1. 定义中间件类型
type Middleware func(http.Handler) http.Handler
  1. 创建拦截器链
func Chain(middlewares ...Middleware) Middleware {
    return func(final http.Handler) http.Handler {
        for i := len(middlewares)-1; i >= 0; i-- {
            final = middlewares[i](final)
        }
        return final
    }
}
  1. 具体拦截器实现
// 日志拦截器
func LoggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("Received %s %s", r.Method, r.URL.Path)
        next.ServeHTTP(w, r)
    })
}

// 认证拦截器
func AuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        token := r.Header.Get("Authorization")
        if token != "valid-token" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        next.ServeHTTP(w, r)
    })
}
  1. 使用示例
func main() {
    finalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello World"))
    })
    
    chain := Chain(LoggingMiddleware, AuthMiddleware)
    http.Handle("/", chain(finalHandler))
    http.ListenAndServe(":8080", nil)
}

这种实现方式支持灵活添加多个拦截器,每个拦截器都可以对请求进行预处理或后处理,实现认证、日志、限流等功能。

更多关于Golang HTTP请求拦截器实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中,HTTP请求拦截器通常通过中间件(Middleware)实现,用于在请求处理前后执行特定逻辑,如认证、日志记录、限流等。以下是几种常见实现方式:

1. 使用标准库的http.Handler接口

package main

import (
    "fmt"
    "net/http"
)

// 拦截器函数类型
type Middleware func(http.Handler) http.Handler

// 日志拦截器
func LoggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Printf("Request: %s %s\n", r.Method, r.URL.Path)
        next.ServeHTTP(w, r) // 调用下一个处理器
    })
}

// 认证拦截器
func AuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        token := r.Header.Get("Authorization")
        if token != "valid-token" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        next.ServeHTTP(w, r)
    })
}

// 实际业务处理器
func helloHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, World!"))
}

func main() {
    handler := http.HandlerFunc(helloHandler)
    
    // 应用拦截器链(注意顺序)
    chain := LoggingMiddleware(AuthMiddleware(handler))
    
    http.Handle("/", chain)
    http.ListenAndServe(":8080", nil)
}

2. 使用第三方库(如Gorilla Mux)

package main

import (
    "github.com/gorilla/mux"
    "net/http"
)

func main() {
    r := mux.NewRouter()
    
    // 全局中间件
    r.Use(LoggingMiddleware)
    r.Use(AuthMiddleware)
    
    r.HandleFunc("/", helloHandler)
    http.ListenAndServe(":8080", r)
}

3. 拦截器链管理

// 组合多个拦截器
func ApplyMiddlewares(h http.Handler, middlewares ...Middleware) http.Handler {
    for i := len(middlewares) - 1; i >= 0; i-- {
        h = middlewares[i](h)
    }
    return h
}

// 使用示例
func main() {
    handler := http.HandlerFunc(helloHandler)
    wrapped := ApplyMiddlewares(handler, LoggingMiddleware, AuthMiddleware)
    http.Handle("/", wrapped)
}

关键点:

  1. 拦截器顺序:从外到内执行(如先日志后认证)
  2. 提前返回:在拦截器中可直接响应并终止请求
  3. 上下文传递:可使用r.Context()在拦截器间传递数据

这种模式灵活且易于测试,是Golang Web开发中的常见实践。

回到顶部