添加中间件之后发现报 EOF
如上图,在加入中间件之后报错。错误的远呀是通过 c.GetRawData() 调用之后 RawData 就没有了,如果不把 RawData 放回去,就会报这个错误
需要在后面添加 c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body)) 将读取的 RawData 放回去
另外,中间件的处理要添加预检请求跳过,否则会看到两次重入的情况
// JWTAuth define the midWare to check whether the JWT is valid
func JWTAuth(c *gin.Context) {
// 如果是预检请求,直接继续处理下一个中间件或处理程序
if c.Request.Method == "OPTIONS" {
c.Next()
return
}
// 所有不包含api开头的请求都不是api接口,不校验权限
if !strings.Contains(c.Request.URL.Path, "/api") {
comm.Log.Infof("JWTAuth %s", c.Request.URL.Path)
c.Next()
return
}
if c.Request.URL.Path == "/api/login" {
c.Next()
return
}
//从头部信息的Authorization中的到tocken
tokenString := c.Request.Header.Get("Authorization")
//如果信息为空
if tokenString == "" {
c.JSON(http.StatusUnauthorized, gin.H{
"code": -1,
"msg": "Authorization header not provided",
})
comm.Log.Errorf("tokenString is empty. %s", tokenString)
c.Abort()
return
}
start := time.Now()
body, _ := c.GetRawData()
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
//将tokenString解析成想要的*MyClaims格式,自定义的函数解析,下面内容有讲解
jwt := NewJWT()
claims, err := jwt.ParseToken(tokenString)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": -1,
"msg": fmt.Sprintf("token parse failed. %s", err.Error()),
})
comm.Log.Errorf("token: *** parse failed. err:%s", tokenString, err.Error())
c.Abort()
return
}
c.Set("claims", claims)
c.Next()
end := time.Now()
latency := end.Sub(start)
// 创建请求日志对象
reqLog := orm.RequestLog{
Method: c.Request.Method,
Path: c.Request.URL.Path,
Status: c.Writer.Status(),
Latency: latency,
ClientIP: c.ClientIP(),
UserAgent: c.Request.UserAgent(),
Body: string(body),
CreatedAt: time.Now(),
UserName: claims.Name,
Role: claims.Role,
}
// 将请求日志保存到数据库
if err := comm.DB.Create(&reqLog).Error; err != nil {
fmt.Println("Failed to save request log to database: ", err)
}
}