<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Gin框架系列03:換個姿勢理解中間件

      什么是中間件

      中間件,英譯middleware,顧名思義,放在中間的物件,那么放在誰中間呢?本來,客戶端可以直接請求到服務端接口。

      file

      現在,中間件橫插一腳,它能在請求到達接口之前攔截請求,做一些特殊處理,比如日志記錄,故障處理等。這就是今天要講述的中間件,那么,它在Gin框架中是怎么使用的呢?

      file

      如何使用中間件

      我們來看一下逢gin必調的方法Default,方法中有一個變量engine,它UseLoggerRecovery兩個函數,這兩個函數就是gin框架的日志和故障處理中間件。

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

      那就很清楚了,使用中間件就是調用Use方法就行了唄,問題是現在除了這兩個中間件還能去Use誰?不如咱先自己寫一個中間件吧,這樣比較容易理解。

      寫一個中間件

      寫啥呢,做產品講究MVP,那咱就寫個最簡單的閉環,攔截請求后輸出平也最帥的日志,產品就可以交付了。

      file

      寫之前先研究一下官方的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看一下,帥呆了,成功渲染數據。

      file

      是不是太簡單了?這就交差了?我還能打十個啊!?

      file

      看來我要把畢生所學都交給你了。

      延伸閱讀

      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, "平也最帥")
        }
      }
      

      file

      Abort

      當然,除了提供Next方法外,理論上也應該有個中斷操作吧,畢竟拿中間件來做授權驗證的話,驗證失敗后還是希望阻斷請求的。所以,Abort就是我們要找的那個方法。拿上面的例子,在平也最帥的下一行調用Abort方法后,Where中間件就不再生效了,于是平也只剩下了單純的帥氣。

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

      file

      局部中間件

      剛才我講的中間件是會在所有的路由上生效的,有些不需要添加中間件的路由場景就無法適應了。所以,我們需要有能為局部添加中間件的能力。

      file

      我們先實現給某個接口單獨加中間件,所以先得定義兩個接口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,加了基本認證的接口,會讓你在訪問接口時提供用戶名與密碼。

      file

      對于瀏覽器用戶,為了用戶的體驗會自動彈出登錄框,而在其他場景下是沒有的,那在哪里輸入賬號密碼呢?實際上,它是通過頭信息傳輸的,頭信息里有一個固定的格式來代表基本認證。

      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語言與技術原理。
      關注我

      posted @ 2020-04-09 16:02  MARIOOW  閱讀(1516)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 亚洲日韩欧洲乱码av夜夜摸| 亚洲乱码一二三四区国产| 亚洲av无码精品色午夜蛋壳| 亚洲最大中文字幕无码网站| 久久国内精品自在自线91| 九九热视频在线观看精品| 亚洲三级香港三级久久| jlzz大jlzz大全免费| 亚洲一区二区三区自拍天堂| 偷拍精品一区二区三区| 激情综合五月网| 一区二区三区久久精品国产| 国产福利酱国产一区二区 | 97se亚洲综合自在线| 亚洲夂夂婷婷色拍ww47| 日韩精品无码一区二区三区视频| 亚洲理论在线A中文字幕| 西林县| 人妻中文字幕精品一页| 成人做受视频试看60秒| 日韩中文字幕有码av| 激情综合色区网激情五月| 久久婷婷大香萑太香蕉AV人| 性一交一乱一伦一| 国产大学生自拍三级视频| 欧美成人精品三级网站视频| 亚洲最大福利视频网| 国产福利深夜在线播放| 美女内射毛片在线看3d| 亚洲欧洲国产综合aⅴ无码| 亚洲国产精品无码一区二区三区| 女人被狂躁的高潮免费视频| 国产永久免费高清在线| 亚洲丶国产丶欧美一区二区三区 | 中文乱码人妻系列一区二区| 91国产自拍一区二区三区| 国产成人综合色就色综合| 曰韩无码av一区二区免费| 夜夜添无码一区二区三区| 一区二区在线欧美日韩中文| jizz视频在线观看|