# 快速使用

Orange 框架中间件是一个用来过滤进入应用 HTTP 请求的工具。可以通过它来方便实现登陆状态校验,权限校验,CSRF验证等等。

实例化中间件以参数形式传递到路由组参数进行申明,该路由组下所有路由将依次执行中间件方法;

app.GroupRouter("/api", NewMiddleWare1(), NewMiddleWare2())` 

# 内置中间件

# 限速中间件

实例化限速中间件 throttle.NewThrottle(maxQps, breakTime, ipSplit)

  • maxQps:触发限速 qps ,当请求达到配置的 qps 数值,后续请求直接返回429错误;
  • breakTime:当触发限速后等待指定时长才能正常访问;
  • ipSplit : 限速是否按 ip 来源区分,true 是, false 否, 按 ip 来源区分,则请求 qps 会根据各个 ip 分别计算,否则直接计算所有请求qps;

相关代码调用:

import (
   "gitee.com/zhucheer/orange/app"
   "gitee.com/zhucheer/orange/middlewares/throttle"

)
...

rateGp :=app.NewRouter("/rate", throttle.NewThrottle(5, time.Minute, true))
...

# CSRF校验

orange 框架已经全局集成 CSRF 校验,通过配置进行开启或关闭,开启后,全局所有 POST 请求都将进行 CSRF校验;

[app]
    ...
    csrfVerify = true # 开启校验

通过控制器 context 参数获取 CSRF-TOKEN,如下:

func ControllerFunc(c *app.Context) error {

   c.ResponseHeader().Set("Content-Type", "application/text")
   return c.ToString(c.CsrfToken)
}

# 异常捕获

在 golang 中如遇到严重的异常或 BUG,往往会导致程序出现 panic 报错,当出现 panic 后程序会终止后续处理,因此我们也无法获取自定义日志等信息,通常我们会通过 defer 和 recover() 来捕获 panic 异常,该内置中间件就是完成 panic 捕获并记录日志的功能; 使用方法:

import (
   "gitee.com/zhucheer/orange/app"
   "gitee.com/zhucheer/orange/middlewares/exception"
)
...

rateGp :=app.NewRouter("/rate", exception.NewPanicReader())
...

注册该中间件后,在web请求中如出现 panic 后页面会输出 500 错误,并且日志会记录一个 Critiacal 级别的错误,我们通过日志可以获取到对应异常具体信息。

# 自定义中间件定义

中间件都放在 middleware 目录下,可以参考内置中间件进行开发;

下面是一个请求 header 头状态检测中间件示例:

package middleware

import (
   "fmt"
   "gitee.com/zhucheer/orange/app"
)

type VerifyHeader struct {
}

func NewVerifyHeader () *VerifyHeader {
   return &VerifyHeader {}
}

// Func implements Middleware interface.
func (w VerifyHeader ) Func() app.MiddlewareFunc {
   return func(next app.HandlerFunc) app.HandlerFunc {
      return func(c *app.Context) error {
       
        // 状态验证逻辑
         fmt.Println("VerifyHeader middleware")
         if c.Request().Header.Get("auth") == "" {
           c.ResponseWrite([]byte("header verify middleware break"))
           return errors.New("header verify middleware break")
         }
         return next(c)

      }
   }
}

...

// routes.go
app.GroupRouter("/api", middleware.NewVerifyHeader())`