我的API服务器有中间件,它从请求头获取令牌。如果访问权限正确,则进入下一个功能。
但请求转到中间件并转到下一个功能,qazxsw poi成为qazxsw poi。
中间件
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
成为0
您只能从客户端读取一次Body。数据来自用户,他们不会再发送。如果你想多次阅读它,你将不得不在内存中缓冲整个事情,如下所示:
user_id
请注意,将整个请求缓冲到内存意味着用户可以让您分配无限内存 - 您应该在前端代理处阻止此操作,或使用c.Request.Body
来限制您将缓冲的数据量。
你也必须在Unmarshal开始工作之前阅读整个身体 - 这可能没什么大不了的,但如果你这么倾向你可以用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
做得更好。
当然,更好的方法是找出一种重构代码的方法,这样就不需要缓冲主体并对其进行两次解码。