目录
  • Golang原生http实现中间件
    • 1 定义http.Handler:具体中间件操作
      • ①CORSMiddleware:允许跨域
      • ②AuthMiddleware:认证
      • ③AuditMiddleware:审计操作
      • ④SmokeHandler:具体处理操作
    • 2 义中间件类型&定义中间件链
      • ①type Middleware func(http.Handler) http.Handler:定义中间件
      • ②定义中间件链MiddlewareChain
    • 3 启动http服务
      • 4 测试
        • 全部代码

        Golang原生http实现中间件

        中间件(middleware):常被用来做认证校验、审计等

        大家常用的Iris、Gin等web框架,都包含了中间件逻辑。但有时我们引入该框架显得较为繁重,本文将介绍通过golang原生http来实现中间件操作。全部代码:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/middleware

        1 定义http.Handler:具体中间件操作

        ①CORSMiddleware:允许跨域

        // CORSMiddleware handles Cross-Origin Resource Sharing (CORS) responses.
        func CORSMiddleware(next http.Handler) http.Handler {
        	fmt.Println("cors middleware....")
        	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        		if r.Method == "OPTIONS" {
        			w.Header().Set("Access-Control-Allow-Origin", "*")
        			w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE")
        			//如果前后端需要传递自定义请求头,需要再Access-Control-Allow-Headers中匹配(Yi-Auth-Token)
        			w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Accept, Yi-Auth-Token")
        			w.WriteHeader(http.StatusOK)
        			return
        		}
        		w.Header().Set("Access-Control-Allow-Origin", "*")
        		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE")
        		w.Header().Set("Access-Control-Allow-Headers", "Content-Type,Accept,Yi-Auth-Token")
        		//交给下一个中间件处理
        		next.ServeHTTP(w, r)
        	})
        }
        

        ②AuthMiddleware:认证

        // AuthMiddleware simulates a simple authentication middleware.
        func AuthMiddleware(next http.Handler) http.Handler {
        	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        		fmt.Println("auth middleware...")
        		//store info in ctx
        		token := r.Header.Get("Token")
        		if len(token) != 0 {
        			//TODO 1. check token 2. get userinfo from token
        			userID := "1"
        			ctx := context.WithValue(r.Context(), "userID", userID)
        			r = r.WithContext(ctx)
        		}
        		next.ServeHTTP(w, r)
        	})
        }
        

        ③AuditMiddleware:审计操作

        // AuditMiddleware simulates an audit logging middleware.
        func AuditMiddleware(next http.Handler) http.Handler {
        	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        		fmt.Println("audit middleware...")
        		next.ServeHTTP(w, r)
        	})
        }
        

        ④SmokeHandler:具体处理操作

        // SmokeHandler returns the current time as a string.
        func SmokeHandler(w http.ResponseWriter, r *http.Request) {
        	fmt.Println("smoke handle....")
        	_, err := w.Write([]byte(time.Now().String()))
        	if err != nil {
        		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
        	}
        }
        

        2 义中间件类型&定义中间件链

        ①type Middleware func(http.Handler) http.Handler:定义中间件

        type Middleware func(http.Handler) http.Handler

        ②定义中间件链MiddlewareChain

        // NewMiddlewareChain creates a new middleware chain with the given middlewares.
        func NewMiddlewareChain(middlewares ...Middleware) Middleware {
        	return func(handler http.Handler) http.Handler {
        		for i := len(middlewares) - 1; i >= 0; i-- {
        			handler = middlewares[i](handler)
        		}
        		return handler
        	}
        }
        

        3 启动http服务

        func RunAndServe() error {
        	defer func() {
        		if e := recover(); e != nil {
        			fmt.Println("err=", e)
        		}
        	}()
        
        	mux := http.NewServeMux()
        
        	// Create middleware chains for routes.
        	authMiddlewareChain := NewMiddlewareChain(CORSMiddleware, AuthMiddleware, AuditMiddleware)
        	//noAuthMiddlewareChain := NewMiddlewareChain(CORSMiddleware)
        
        	// Convert the middleware chain result to http.HandlerFunc.
        	smokeHandlerWrapped := func(w http.ResponseWriter, r *http.Request) {
        		authMiddlewareChain(http.HandlerFunc(SmokeHandler)).ServeHTTP(w, r)
        	}
        
        	mux.HandleFunc("/smoke", smokeHandlerWrapped)
        
        	fmt.Printf("listening on http://localhost:%d\n", 9999)
        	return http.ListenAndServe(":9999", mux)
        }
        

        4 测试

        启动后端

        go run main.go
        

        Golang使用原生http实现中间件的代码详解

        2. 浏览器访问http://localhost:9999/smoke

        Golang使用原生http实现中间件的代码详解

        3. 后端日志打印

        可以看到是最后才处理我们的业务Handler

        Golang使用原生http实现中间件的代码详解

        全部代码

        package main
        
        import (
        	"context"
        	"fmt"
        	"net/http"
        	"time"
        )
        
        type Middleware func(http.Handler) http.Handler
        
        // CORSMiddleware handles Cross-Origin Resource Sharing (CORS) responses.
        func CORSMiddleware(next http.Handler) http.Handler {
        	fmt.Println("cors middleware....")
        	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        		if r.Method == "OPTIONS" {
        			w.Header().Set("Access-Control-Allow-Origin", "*")
        			w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE")
        			//如果前后端需要传递自定义请求头,需要再Access-Control-Allow-Headers中匹配(Yi-Auth-Token)
        			w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Accept, Yi-Auth-Token")
        			w.WriteHeader(http.StatusOK)
        			return
        		}
        		w.Header().Set("Access-Control-Allow-Origin", "*")
        		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE")
        		w.Header().Set("Access-Control-Allow-Headers", "Content-Type,Accept,Yi-Auth-Token")
        		next.ServeHTTP(w, r)
        	})
        }
        
        // AuthMiddleware simulates a simple authentication middleware.
        func AuthMiddleware(next http.Handler) http.Handler {
        	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        		fmt.Println("auth middleware...")
        		//store info in ctx
        		token := r.Header.Get("Token")
        		if len(token) != 0 {
        			//TODO 1. check token 2. get userinfo from token
        			userID := "1"
        			ctx := context.WithValue(r.Context(), "userID", userID)
        			r = r.WithContext(ctx)
        		}
        		next.ServeHTTP(w, r)
        	})
        }
        
        // AuditMiddleware simulates an audit logging middleware.
        func AuditMiddleware(next http.Handler) http.Handler {
        	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        		fmt.Println("audit middleware...")
        		next.ServeHTTP(w, r)
        	})
        }
        
        // SmokeHandler returns the current time as a string.
        func SmokeHandler(w http.ResponseWriter, r *http.Request) {
        	fmt.Println("smoke handle....")
        	_, err := w.Write([]byte(time.Now().String()))
        	if err != nil {
        		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
        	}
        }
        
        // NewMiddlewareChain creates a new middleware chain with the given middlewares.
        func NewMiddlewareChain(middlewares ...Middleware) Middleware {
        	return func(handler http.Handler) http.Handler {
        		for i := len(middlewares) - 1; i >= 0; i-- {
        			handler = middlewares[i](handler)
        		}
        		return handler
        	}
        }
        
        func RunAndServe() error {
        	defer func() {
        		if e := recover(); e != nil {
        			fmt.Println("err=", e)
        		}
        	}()
        
        	mux := http.NewServeMux()
        
        	// Create middleware chains for routes.
        	authMiddlewareChain := NewMiddlewareChain(CORSMiddleware, AuthMiddleware, AuditMiddleware)
        	//noAuthMiddlewareChain := NewMiddlewareChain(CORSMiddleware)
        
        	// Convert the middleware chain result to http.HandlerFunc.
        	smokeHandlerWrapped := func(w http.ResponseWriter, r *http.Request) {
        		authMiddlewareChain(http.HandlerFunc(SmokeHandler)).ServeHTTP(w, r)
        	}
        
        	mux.HandleFunc("/smoke", smokeHandlerWrapped)
        
        	fmt.Printf("listening on http://localhost:%d\n", 9999)
        	return http.ListenAndServe(":9999", mux)
        }
        
        func main() {
        	RunAndServe()
        }
        

        以上就是Golang使用原生http实现中间件的代码详解的详细内容,更多关于Golang http中间件的资料请关注其它相关文章!

        声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。