新聞中心
基本介紹
?HTTPClient?支持強大的攔截器/中間件特性,該特性使得對于客戶端的全局請求攔截及注入成為了可能,例如修改/注入提交參數(shù)、修改/注入返回參數(shù)、基于客戶端的參數(shù)校驗等等。中間件的注入通過以下方法實現(xiàn):

創(chuàng)新互聯(lián)公司堅持“要么做到,要么別承諾”的工作理念,服務領(lǐng)域包括:網(wǎng)站制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務,滿足客戶于互聯(lián)網(wǎng)時代的德欽網(wǎng)站設計、移動媒體設計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡建設合作伙伴!
func (c *Client) Use(handlers ...HandlerFunc) *Client在中間件中通過?Next?方法執(zhí)行下一步流程,?Next?方法定義如下:
func (c *Client) Next(req *http.Request) (*Response, error)
中間件類型
?HTTPClient?中間件功能同?HTTPServer?的中間件功能類似,同樣也是分為了前置中間件和后置中間件兩種。
前置中間件
處理邏輯位于?Next?方法之前,格式形如:
c := g.Client()
c.Use(func(c *gclient.Client, r *http.Request) (resp *gclient.Response, err error) {
// 自定義處理邏輯
return c.Next(r)
})
后置中間件
處理邏輯位于?Next?方法之后,格式形如:
c := g.Client()
c.Use(func(c *ghttp.Client, r *http.Request) (resp *ghttp.ClientResponse, err error) {
resp, err = c.Next(r)
// 自定義處理邏輯
return resp, err
})
使用示例
我們來一個代碼示例更好介紹使用,該示例通過給客戶端增加攔截器,對提交的?JSON?數(shù)據(jù)注入自定義的額外參數(shù),這些額外參數(shù)實現(xiàn)對提交參數(shù)的簽名生成體積簽名相關(guān)參數(shù)提交,也就是實現(xiàn)一版簡單的接口參數(shù)安全校驗。
服務端
服務端的邏輯很簡單,就是把客戶端提交的?JSON?參數(shù)按照?map?解析后再構(gòu)造成?JSON?字符串返回給客戶端。
package main
import (
"github.com/GOgf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
func main() {
s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {
group.ALL("/", func(r *ghttp.Request) {
r.Response.Write(r.GetMap())
})
})
s.SetPort(8199)
s.Run()
}
客戶端
客戶端的邏輯是實現(xiàn)基本的客戶端參數(shù)提交、攔截器注入、簽名相關(guān)參數(shù)注入以及簽名參數(shù)生成。
package main
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/internal/json"
"github.com/gogf/gf/v2/net/gclient"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/guid"
"github.com/gogf/gf/v2/util/gutil"
)
const (
appId = "123"
appSecret = "456"
)
// 注入統(tǒng)一的接口簽名參數(shù)
func injectSignature(jsonContent []byte) []byte {
var m map[string]interface{}
_ = json.Unmarshal(jsonContent, &m)
if len(m) > 0 {
m["appid"] = appId
m["nonce"] = guid.S()
m["timestamp"] = gtime.Timestamp()
var (
keyArray = garray.NewSortedStrArrayFrom(gutil.Keys(m))
sigContent string
)
keyArray.Iterator(func(k int, v string) bool {
sigContent += v
sigContent += gconv.String(m[v])
return true
})
m["signature"] = gmd5.MustEncryptString(gmd5.MustEncryptString(sigContent) + appSecret)
jsonContent, _ = json.Marshal(m)
}
return jsonContent
}
func main() {
c := g.Client()
c.Use(func(c *gclient.Client, r *http.Request) (resp *gclient.Response, err error) {
bodyBytes, _ := ioutil.ReadAll(r.Body)
if len(bodyBytes) > 0 {
// 注入簽名相關(guān)參數(shù),修改Request原有的提交參數(shù)
bodyBytes = injectSignature(bodyBytes)
r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
r.ContentLength = int64(len(bodyBytes))
}
return c.Next(r)
})
content := c.ContentJson().PostContent(gctx.New(), "http://127.0.0.1:8199/", g.Map{
"name": "GoFrame",
"site": "https://goframe.org",
})
fmt.Println(content)
}
運行測試
先運行服務端:
$ go run server.go
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
----------|---------|---------|--------|-------|-------------------|-------------
default | default | :8199 | ALL | / | main.main.func1.1 |
----------|---------|---------|--------|-------|-------------------|-------------
2021-05-18 09:23:41.865 97906: http server started listening on [:8199]再運行客戶端:
$ go run client.go
{"appid":"123","name":"goframe","nonce":"12vd8tx23l6cbfz9k59xehk1002pixfo","signature":"578a90b67bdc63d551d6a18635307ba2","site":"https://goframe.org","timestamp":1621301076}
$ 可以看到,服務端接受到的參數(shù)多了多了幾項,包括?appid/nonce/timestamp/signature?,這些參數(shù)往往都是簽名校驗算法所需要的參數(shù)。
當前標題:創(chuàng)新互聯(lián)GoFrame教程:GoFrameHTTPClient-攔截器/中間件
轉(zhuǎn)載注明:http://www.dlmjj.cn/article/dhdodjs.html


咨詢
建站咨詢
