gpt4 book ai didi

go - Gin如果 `request body`绑定(bind)到中间件,c.Request.Body变为0

转载 作者:IT王子 更新时间:2023-10-29 02:32:04 25 4
gpt4 key购买 nike

我的 API 服务器有中间件,它从请求 header 中获取 token 。如果访问正确,则进入下一个功能。

但是request去了中间件,去了下一个函数,c.Request.Body变成了0

中间件

func getUserIdFromBody(c *gin.Context) (int) {
var jsonBody User

length, _ := strconv.Atoi(c.Request.Header.Get("Content-Length"))
body := make([]byte, length)
length, _ = c.Request.Body.Read(body)
json.Unmarshal(body[:length], &jsonBody)

return jsonBody.Id
}

func CheckToken() (gin.HandlerFunc) {
return func(c *gin.Context) {
var userId int

config := model.NewConfig()

reqToken := c.Request.Header.Get("token")

_, resBool := c.GetQuery("user_id")
if resBool == false {
userId = getUserIdFromBody(c)
} else {
userIdStr := c.Query("user_id")
userId, _ = strconv.Atoi(userIdStr)
}
...
if ok {
c.Nex()
return
}
}

下一个函数

func bindOneDay(c *gin.Context) (model.Oneday, error) {
var oneday model.Oneday

if err := c.BindJSON(&oneday); err != nil {
return oneday, err
}
return oneday, nil
}

bindOneDay 返回带有 EOF 的错误。因为 c.Request.Body 可能是 0

我想从中间件的请求体中获取user_idc.Request.Body 变成 0 怎么办才没有问题

最佳答案

您只能从客户端读取一次 Body。数据是从用户那里流出来的,他们不会再发送它。如果您想多次阅读它,您将不得不在内存中缓冲整个内容,如下所示:

bodyCopy := new(bytes.Buffer)
// Read the whole body
_, err := io.Copy(bodyCopy, req.Body)
if err != nil {
return err
}
bodyData := bodyCopy.Bytes()
// Replace the body with a reader that reads from the buffer
req.Body = ioutil.NopCloser(bytes.NewReader(bodyData))
// Now you can do something with the contents of bodyData,
// like passing it to json.Unmarshal

请注意,将整个请求缓冲到内存中意味着用户可能会导致您分配无限内存——您可能应该在前端代理中阻止它或使用 io.LimitedReader 来限制您将缓冲的数据量。

在 Unmarshal 开始工作之前,您还必须阅读整个正文——这可能没什么大不了的,但您可以使用 io.TeeReaderjson.NewDecoder< 做得更好 如果你愿意的话。

当然,更好的方法是找出一种重组代码的方法,这样就不需要缓冲正文并将其解码两次。

关于go - Gin如果 `request body`绑定(bind)到中间件,c.Request.Body变为0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47990026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com