You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
kratos/doc/wiki-cn/blademaster-mid.md

3.7 KiB

背景

基于bm的handler机制,可以自定义很多middleware(中间件)进行通用的业务处理,比如用户登录鉴权。接下来就以鉴权为例,说明middleware的写法和用法。

写自己的中间件

middleware本质上就是一个handler,如下代码:

// Handler responds to an HTTP request.
type Handler interface {
	ServeHTTP(c *Context)
}

// HandlerFunc http request handler function.
type HandlerFunc func(*Context)

// ServeHTTP calls f(ctx).
func (f HandlerFunc) ServeHTTP(c *Context) {
	f(c)
}
  1. 实现了Handler接口,可以作为engine的全局中间件使用:engine.Use(YourHandler)
  2. 声明为HandlerFunc方法,可以作为router的局部中间件使用:e.GET("/path", YourHandlerFunc)

简单示例代码如下:

type Demo struct {
	Key   string
	Value   string
}
// ServeHTTP implements from Handler interface
func (d *Demo) ServeHTTP(ctx *bm.Context) {
	ctx.Set(d.Key, d.Value)
}

e := bm.DefaultServer(nil)
d := &Demo{}

// Handler使用如下:
e.Use(d)

// HandlerFunc使用如下:
e.GET("/path", d.ServeHTTP)

// 或者只有方法
myHandler := func(ctx *bm.Context) {
    // some code
}
e.GET("/path", myHandler)

全局中间件

在blademaster的server.go代码中,有以下代码:

func DefaultServer(conf *ServerConfig) *Engine {
	engine := NewServer(conf)
	engine.Use(Recovery(), Trace(), Logger())
	return engine
}

会默认创建一个bm engine,并注册Recovery(), Trace(), Logger()三个middlerware,用于全局handler处理。优先级从前到后。
如果需要自定义默认全局执行的middleware,可以使用NewServer方法创建一个无middleware的engine对象。
如果想要将自定义的middleware注册进全局,可以继续调用Use方法如下:

engine.Use(YourMiddleware())

此方法会将YourMiddleware追加到已有的全局middleware后执行。

局部中间件

先来看一段示例(代码再pkg/net/http/blademaster/middleware/auth模块下):

func Example() {
	myHandler := func(ctx *bm.Context) {
		mid := metadata.Int64(ctx, metadata.Mid)
		ctx.JSON(fmt.Sprintf("%d", mid), nil)
	}

	authn := auth.New(&auth.Config{DisableCSRF: false})

	e := bm.DefaultServer(nil)

	// "/user"接口必须保证登录用户才能访问,那么我们加入"auth.User"来确保用户鉴权通过,才能进入myHandler进行业务逻辑处理
	e.GET("/user", authn.User, myHandler)
	// "/guest"接口访客用户就可以访问,但如果登录用户我们需要知道mid,那么我们加入"auth.Guest"来尝试鉴权获取mid,但肯定会继续执行myHandler进行业务逻辑处理
	e.GET("/guest", authn.Guest, myHandler)

    // "/owner"开头的所有接口,都需要进行登录鉴权才可以被访问,那可以创建一个group并加入"authn.User"
	o := e.Group("/owner", authn.User)
	o.GET("/info", myHandler) // 该group创建的router不需要再显示的加入"authn.User"
	o.POST("/modify", myHandler) // 该group创建的router不需要再显示的加入"authn.User"

	e.Start()
}

内置中间件

自适应限流

更多关于自适应限流的信息,请参考:kratos 自适应限流

func Example() {
	myHandler := func(ctx *bm.Context) {
    		mid := metadata.Int64(ctx, metadata.Mid)
    		ctx.JSON(fmt.Sprintf("%d", mid), nil)
    	}
    
    
    	e := bm.DefaultServer(nil)
    
    	// 挂载自适应限流中间件到 bm engine,使用默认配置
    	limiter := bm.NewRateLimiter(nil)
    	e.Use(limiter.Limit())
    
    	e.GET("/user", myHandler)
    
    	e.Start()
}

扩展阅读

bm快速开始
bm模块说明
bm基于pb生成


文档目录树