什么是中心件

中心件,英译middleware,顾名思义,放在中心的物件,那么放在谁中心呢?原本,客户端可以直接请求到服务端接口。

现在,中心件横插一脚,它能在请求到达接口之前阻挡请求,做一些特殊处置,好比日志纪录,故障处置等。这就是今天要讲述的中心件,那么,它在Gin框架中是怎么使用的呢?

若何使用中心件

我们来看一下逢gin必调的方式Default,方式中有一个变量engine,它UseLoggerRecovery两个函数,这两个函数就是gin框架的日志和故障处置中心件。

func Default() *Engine {
	debugPrintWARNINGDefault()
	engine := New()
	engine.Use(Logger(), Recovery())
	return engine
}

那就很清晰了,使用中心件就是挪用Use方式就行了呗,问题是现在除了这两个中心件还能去Use谁?不如咱先自己写一个中心件吧,这样对照容易明了。

写一个中心件

写啥呢,做产物讲求MVP,那咱就写个最简朴的闭环,阻挡请求后输出平也最帅的日志,产物就可以交付了。

写之前先研究一下官方的LoggerRecovery是怎么写的,好比葫芦画瓢。

func Logger() HandlerFunc {
	return LoggerWithConfig(LoggerConfig{})
}

func Recovery() HandlerFunc {
	return RecoveryWithWriter(DefaultErrorWriter)
}

原来这两个函数都返回了HandlerFunc类型,那我们也模拟写一个函数就好了。

func PingYe() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.String(200, "平也最帅")
	}
}

很简朴,写完了,可以在main函数中Use它了。

func main() {
	r := gin.Default()
	r.Use(PingYe())
	r.Run()
}

把项目跑起来,接见localhsot:8080看一下,帅呆了,乐成渲染数据。

是不是太简朴了?这就交差了?我还能打十个啊!?

看来我要把毕生所学都交给你了。

延伸阅读

Next

若是我们界说了两个中心件,一个是平也最帅,另一个是在那里最帅。

func PingYe() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.String(200, "平也最帅")
	}
}

func Where() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.String(200, "在全宇宙")
	}
}

按顺序把它们划分注册到框架当中,这个时刻我们预测它会先输出平也最帅再输出在全宇宙对吧?对,确实是的。

func main() {
	r := gin.Default()
	r.Use(PingYe(), Where())
	r.Run()
}

然则,若是我在不更改注册顺序的前提下,怎么换取一下顺序,先输出在全宇宙再输出平也最帅呢?这就用到了赫赫有名的Next方式。它的作用就是先执行以下一个中心件,执行完了再回来继续执行接下来的逻辑。记得是在中心件中挪用哦~

func PingYe() gin.HandlerFunc {
  return func(c *gin.Context) {
    c.Next()
    c.String(200, "平也最帅")
  }
}

Abort

固然,除了提供Next方式外,理论上也应该有个中止操作吧,究竟拿中心件来做授权验证的话,验证失败后照样希望阻断请求的。以是,Abort就是我们要找的谁人方式。拿上面的例子,在平也最帅的下一行挪用Abort方式后,Where中心件就不再生效了,于是平也只剩下了单纯的帅气。

func PingYe() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.String(200, "平也最帅")
		c.Abort()
	}
}

局部中心件

适才我讲的中心件是会在所有的路由上生效的,有些不需要添加中心件的路由场景就无法顺应了。以是,我们需要有能为局部添加中心件的能力。

我们先实现给某个接口单独加中心件,以是先得界说两个接口knowunknown,划分代表熟悉平也与不熟悉两个场景,鉴于熟悉后才知道平也是全宇宙最帅的,以是要绑中心件,不熟悉就算了。实现方式异常简朴,往路由后面的参数拼命加中心件就好了。

r.GET("know", PingYe(), Where())
r.GET("unknown", func(c *gin.Context) {
  c.String(200, "???")
})

除了针对某个接口添加中心件外,还可以针对一组接口添加,同样挪用Use方式即可。

v1 := r.Group("v1")
v1.Use(PingYe(), Where())
{
  v1.GET("/know", func(c *gin.Context) {
    c.String(200, "know")
  })
  v1.GET("/unknown", func(c *gin.Context) {
    c.String(200, "unknown")
  })
}

HTTP基本认证

基本认证,又称BasicAuth,加了基本认证的接口,会让你在接见接口时提供用户名与密码。

对于浏览器用户,为了用户的体验会自动弹出登录框,而在其他场景下是没有的,那在那里输入账号密码呢?实际上,它是通过头信息传输的,头信息里有一个牢固的花样来代表基本认证。

Authorization: Basic <凭证>

凭证部门是是用户名和密码组合的base64编码,两者以冒号方式拼接。然鹅,gin框架的BaseAuth中心件早已准备好了一切,它可以短短几行代码就能剖析基本认证的信息。

func main() {
	r := gin.Default()
	r.Use(gin.BasicAuth(gin.Accounts{
		"pingye": "123",
	}))
	r.GET("/secrets", func(c *gin.Context) {
		user := c.MustGet(gin.AuthUserKey).(string)
		c.String(200, user+"已登录乐成")
	})
	r.Run()
}

示例中的部门代码可能有些同砚不太明了,好比BasicAuth方式中的参数,由于基本认证需要账号和密码对吧,以是我们可以行使gin.Accounts利便的设置好需要验证的账号密码,gin.Accounts是一个map类型,键代表用户名,值代表密码,固然可以设置不止一个键值对,凭据你的喜欢自行设置。

代码中还泛起了c.MustGet方式,这个方式的作用就是一定要取到某个参数,取不到就不干了panic,取的是什么呢?就是gin.AuthUserKey,在官方中的注释是基本认证中用户凭证的cookie名称。

// AuthUserKey is the cookie name for user credential in basic auth.
const AuthUserKey = "user"

Go语言库示例开源项目「golang-examples」迎接star~

https://github.com/pingyeaa/golang-examples

谢谢人人的旁观,若是以为文章对你有所辅助,迎接关注民众号「平也」,聚焦Go语言与手艺原理。

,

阳光娱乐

阳光娱乐(原诚信在线官网)现已开放阳光在线手机版、阳光在线电脑客户端下载。阳光在线娱乐戏公平、公开、公正,用实力赢取信誉。

Allbet Gaming声明:该文看法仅代表作者自己,与阳光在线无关。转载请注明:天津景点排行榜:Gin框架系列03:换个姿势明白中间件
发布评论

分享到:

allbet官网娱乐平台开户:忘不了女排19号!韩国最正球员李多英 网友:恋爱了
1 条回复
  1. 环球UG官网开户网址
    环球UG官网开户网址
    (2020-06-24 00:38:37) 1#

    联博以太坊高度www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。还好啦。

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。