欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go 微服務(wù)框架kratos使用中間件的方法

 更新時(shí)間:2024年05月28日 14:35:23   作者:龍門吹雪  
在go語言中,中間件是一種用于處理http請(qǐng)求的開發(fā)模式,允許開發(fā)人員在請(qǐng)求到達(dá)處理程序之前或之后執(zhí)行特定的操作,如日志記錄、身份驗(yàn)證、錯(cuò)誤處理等,這篇文章主要介紹了go 微服務(wù)框架kratos使用中間件的方法,需要的朋友可以參考下

一、中間件的概念

在go語言中,中間件是一種用于處理http請(qǐng)求的開發(fā)模式,允許開發(fā)人員在請(qǐng)求到達(dá)處理程序之前或之后執(zhí)行特定的操作,如日志記錄、身份驗(yàn)證、錯(cuò)誤處理等。

中間件通常是一個(gè)函數(shù),它接收一個(gè) `http.Handler` 作為參數(shù)并返回另一個(gè) `http.Handler`。

go源碼中 Handler 的定義如下:

type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

二、go原生http中使用中間件的方法

使用方法:

1、創(chuàng)建中間件函數(shù),輸入?yún)?shù) http.Handler,輸出參數(shù) http.Handler

2、將處理器函數(shù)作為參數(shù)傳入上述中間件函數(shù)

3、運(yùn)用 Handle(pattern string, handler Handler) 等函數(shù)將中間件函數(shù)綁定到請(qǐng)求路由中

代碼示例:

package main
import (
	"fmt"
	"log"
	"net/http"
)
// 日志記錄中間件
func loggingMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("請(qǐng)求處理之前   Request URI: %s\n", r.RequestURI)
		next.ServeHTTP(w, r)
		log.Printf("處理程序之后進(jìn)行的操作...\n")
	})
}
// handler 處理函數(shù)
func SayHello(w http.ResponseWriter, r *http.Request) {
	fmt.Println("Hello world")
}
func main() {
	//創(chuàng)建一個(gè) HTTP 請(qǐng)求路由器
	mux := http.NewServeMux()
	// 使用日志記錄中間件
	mux.Handle("/index", loggingMiddleware(http.HandlerFunc(SayHello)))
	//啟動(dòng)服務(wù),使用創(chuàng)建的 ServeMux
	http.ListenAndServe(":8081", mux)
}

運(yùn)行效果:

三、go微服務(wù)框架Kratos使用中間件的方法

kratos介紹中間件的官網(wǎng)地址:概覽 | Kratos

1、內(nèi)置中間件使用方法

①通過 Middleware(m ...middleware.Middleware) ServerOption 添加所需的中間件

②將上述由中間件組成的 ServerOption 添加到 []http.ServerOption 中

③通過函數(shù) NewServer(opts ...ServerOption) *Server 創(chuàng)建 httpServer

代碼示例:

func NewHTTPServer(c *conf.Server, logger log.Logger, blog *service.BlogService) *http.Server {
	opts := []http.ServerOption{
		http.Middleware(
			//使用kratos內(nèi)置中間件
			recovery.Recovery(),
			tracing.Server(),
			logging.Server(logger),
			validate.Validator(),
		),
	}
	if c.Http.Network != "" {
		opts = append(opts, http.Network(c.Http.Network))
	}
	if c.Http.Addr != "" {
		opts = append(opts, http.Address(c.Http.Addr))
	}
	if c.Http.Timeout != nil {
		opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
	}
	//創(chuàng)建 httpServer 
	srv := http.NewServer(opts...)
	v1.RegisterBlogServiceHTTPServer(srv, blog)
	return srv
}

2、自定義中間件使用方法

①實(shí)現(xiàn) middleware.Middleware 接口,其定義如下:

// Handler defines the handler invoked by Middleware.
type Handler func(ctx context.Context, req interface{}) (interface{}, error)
// Middleware is HTTP/gRPC transport middleware.
type Middleware func(Handler) Handler

中間件中您可以使用 tr, ok := transport.FromServerContext(ctx) 獲得 Transporter 實(shí)例以便訪問接口相關(guān)的元信息。

②像添加內(nèi)置中間件一樣,將自定義中間件添加到 http.Middleware 和 []http.ServerOption 中

③通過函數(shù) NewServer(opts ...ServerOption) *Server 創(chuàng)建 httpServer

代碼示例:

// auth.go 單元
//自定義 JWT 認(rèn)證中間件
func JWTAuth(jwtSecret string) middleware.Middleware {
	return func(handler middleware.Handler) middleware.Handler {
		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
			if tr, ok := transport.FromServerContext(ctx); ok {
				tokenString := tr.RequestHeader().Get("authorization")
				spew.Dump(tokenString)
				//token, err := jwt.ParseWithClaims(tokenString, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) {
				token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
					// Don't forget to validate the alg is what you expect:
					if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
						return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
					}
					// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
					return []byte(jwtSecret), nil
				})
				if err != nil {
					log.Fatal(err)
				}
				if claims, ok := token.Claims.(jwt.MapClaims); ok {
					fmt.Println(claims["iss"], claims["exp"])
					//fmt.Println(claims.Issuer, claims.ExpiresAt)
				} else {
					fmt.Println(err)
				}
			}
			return handler(ctx, req)
		}
	}
}
// server/http.go 單元
func NewHTTPServer(c *conf.Server, confAuth *conf.Auth, logger log.Logger, blog *service.BlogService) *http.Server {
	opts := []http.ServerOption{
		http.Middleware(
			//自定義中間件 JWTAuth
			auth.JWTAuth(confAuth.JwtSecrect),
		),
	}
	if c.Http.Network != "" {
		opts = append(opts, http.Network(c.Http.Network))
	}
	if c.Http.Addr != "" {
		opts = append(opts, http.Address(c.Http.Addr))
	}
	if c.Http.Timeout != nil {
		opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
	}
	//創(chuàng)建 httpServer 
	srv := http.NewServer(opts...)
	v1.RegisterBlogServiceHTTPServer(srv, blog)
	return srv
}

3、為特定路由定制中間件的使用方法

使用方法:

對(duì)特定路由定制中間件:

server: selector.Server(ms...)

client: selector.Client(ms...)

代碼示例:

// server/http.go 單元
// 添加驗(yàn)證白名單
func NewWhiteListMatcher() selector.MatchFunc {
	whiteList := make(map[string]struct{})
	whiteList["/blog.api.v1.Account/Login"] = struct{}{}
	whiteList["/blog.api.v1.Account/Register"] = struct{}{}
	return func(ctx context.Context, operation string) bool {
		if _, ok := whiteList[operation]; ok {
			return false
		}
		return true
	}
}
// server/http.go 單元
func NewHTTPServer(c *conf.Server, confAuth *conf.Auth, logger log.Logger, blog *service.BlogService) *http.Server {
	opts := []http.ServerOption{
		http.Middleware(
			//自定義中間件 JWTAuth
			selector.Server(auth.JWTAuth(confAuth.JwtSecrect)).
				Match(NewWhiteListMatcher()).
				Build(),
		),
	}
	if c.Http.Network != "" {
		opts = append(opts, http.Network(c.Http.Network))
	}
	if c.Http.Addr != "" {
		opts = append(opts, http.Address(c.Http.Addr))
	}
	if c.Http.Timeout != nil {
		opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
	}
	//創(chuàng)建 httpServer 
	srv := http.NewServer(opts...)
	v1.RegisterBlogServiceHTTPServer(srv, blog)
	return srv
}

注意: 定制中間件是通過 operation 匹配,并不是 http 本身的路由?。。?/strong>

gRPC path 的拼接規(guī)則為 /包名.服務(wù)名/方法名(/package.Service/Method)。

到此這篇關(guān)于go 微服務(wù)框架kratos使用中間件的方法的文章就介紹到這了,更多相關(guān)go 微服務(wù)框架kratos使用中間件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解如何使用Golang擴(kuò)展Envoy

    詳解如何使用Golang擴(kuò)展Envoy

    這篇文章主要為大家介紹了詳解如何使用Golang擴(kuò)展Envoy實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Golang Gorm實(shí)現(xiàn)自定義多態(tài)模型關(guān)聯(lián)查詢

    Golang Gorm實(shí)現(xiàn)自定義多態(tài)模型關(guān)聯(lián)查詢

    GORM 是一個(gè)流行的開源 ORM (Object-Relational Mapping) 庫,專為 Go 語言設(shè)計(jì),它簡(jiǎn)化了與 SQL 數(shù)據(jù)庫的交互,GORM 封裝了數(shù)據(jù)庫操作,使得開發(fā)者能夠通過簡(jiǎn)單的鏈?zhǔn)秸{(diào)用來執(zhí)行 CRUD,本文給大家介紹了Golang Gorm實(shí)現(xiàn)自定義多態(tài)模型關(guān)聯(lián)查詢,需要的朋友可以參考下
    2024-11-11
  • Go語言中的值類型與引用類型的使用

    Go語言中的值類型與引用類型的使用

    Go語言中的數(shù)據(jù)類型可以分為值類型和引用類型,值類型包括基本和復(fù)合數(shù)據(jù)類型,特點(diǎn)是在傳遞時(shí)進(jìn)行復(fù)制,保證數(shù)據(jù)的安全性,引用類型如slice、map等,傳遞的是引用副本,便于大型數(shù)據(jù)操作且提高性能,理解這些概念有助于編寫更高效、安全的Go代碼
    2024-09-09
  • Golang開發(fā)中如何解決共享變量問題

    Golang開發(fā)中如何解決共享變量問題

    Go提供了傳統(tǒng)通過共享變量,也就是共享內(nèi)存的方式來實(shí)現(xiàn)并發(fā)。這篇文章會(huì)介紹 Go提供的相關(guān)機(jī)制,對(duì)Golang共享變量相關(guān)知識(shí)感興趣的朋友一起看看吧
    2021-09-09
  • Go代碼檢查的推薦工具及使用詳解

    Go代碼檢查的推薦工具及使用詳解

    這篇文章主要為大家介紹了Go代碼檢查的推薦工具及使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 淺析Go語言中閉包的使用

    淺析Go語言中閉包的使用

    閉包是一個(gè)函數(shù)和其相關(guān)的引用環(huán)境組合的一個(gè)整體。本文主要為大家介紹一下Go語言中閉包的使用,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語言有一定幫助,需要的可以參考一下
    2022-12-12
  • 構(gòu)建Golang應(yīng)用最小Docker鏡像的實(shí)現(xiàn)

    構(gòu)建Golang應(yīng)用最小Docker鏡像的實(shí)現(xiàn)

    這篇文章主要介紹了構(gòu)建Golang應(yīng)用最小Docker鏡像的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 一文帶你探索Golang計(jì)時(shí)器的奧秘

    一文帶你探索Golang計(jì)時(shí)器的奧秘

    在?Golang?中,計(jì)時(shí)器(timer)是一種常見的工具,用于定期執(zhí)行某個(gè)任務(wù)或者在指定時(shí)間后觸發(fā)某個(gè)事件。本文將深入探討?Golang?計(jì)時(shí)器的實(shí)現(xiàn)原理和使用方法,幫助大家更好地理解和應(yīng)用計(jì)時(shí)器
    2023-05-05
  • Golang實(shí)現(xiàn)復(fù)合數(shù)據(jù)類型

    Golang實(shí)現(xiàn)復(fù)合數(shù)據(jù)類型

    Go語言的復(fù)合數(shù)據(jù)類型包括數(shù)組、切片、映射、結(jié)構(gòu)體和接口,本文就來介紹一下Golang實(shí)現(xiàn)復(fù)合數(shù)據(jù)類型,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-02-02
  • gRPC超時(shí)攔截器實(shí)現(xiàn)示例

    gRPC超時(shí)攔截器實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了gRPC超時(shí)攔截器實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06

最新評(píng)論