Files
HomeDash-Backend/internal/global/g_middleware/middleware.go
2023-10-03 15:57:52 +08:00

192 lines
4.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package g_middleware
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/glog"
"github.com/golang-jwt/jwt/v5"
"home-network-watcher/manifest"
"sync"
"time"
)
type sMiddleware struct{} // 创建结构体
var (
once = &sync.Once{} // 创建互锁
s *sMiddleware // 创建指针
SMiddlewares = newMiddleware() // 对外暴露
)
// defaultHandlerResponse 返回结构体
type defaultHandlerResponse struct {
Status int `json:"status" dc:"Error code"` // 可业务需要可以更改json字段
Message string `json:"msg" dc:"Error message"`
Data interface{} `json:"data" dc:"Result data for certain request according API definition"`
}
// newMiddleware 单例中间件
func newMiddleware() *sMiddleware {
once.Do(func() {
s = &sMiddleware{}
})
return s
}
func (s *sMiddleware) MiddlewareCORS(r *ghttp.Request) {
r.Response.CORSDefault()
r.Middleware.Next()
}
// resWriteJson 返回json输出
func (s *sMiddleware) resWriteJson(r *ghttp.Request, in defaultHandlerResponse) {
r.Response.ClearBuffer()
r.Response.WriteJson(defaultHandlerResponse{
Status: in.Status,
Message: in.Message,
Data: in.Data,
})
}
// ErrorsStatus 服务器错误码处理
func (s *sMiddleware) ErrorsStatus(server *ghttp.Server) {
server.BindStatusHandlerByMap(map[int]ghttp.HandlerFunc{
500: func(r *ghttp.Request) {
s.resWriteJson(r, defaultHandlerResponse{
Status: 500,
Message: "Error 500,Internal Server Error",
Data: "",
})
},
404: func(r *ghttp.Request) {
s.resWriteJson(r, defaultHandlerResponse{
Status: 404,
Message: "Error 404,Not Found",
Data: "",
})
},
})
}
// JWTAuth 鉴权中间件
func (s *sMiddleware) JWTAuth(r *ghttp.Request) {
JWTString := r.GetHeader("Authorization")
if JWTString == "" {
s.resWriteJson(r, defaultHandlerResponse{
Status: 401,
Message: "JWT为空",
Data: nil,
})
return
}
// 验证JWT
token, err := jwt.Parse(JWTString, func(token *jwt.Token) (interface{}, error) {
return manifest.JWTKey, nil
})
if err != nil {
s.resWriteJson(r, defaultHandlerResponse{
Status: 401,
Message: "JWT验证失败",
Data: nil,
})
return
}
if !token.Valid {
s.resWriteJson(r, defaultHandlerResponse{
Status: 401,
Message: "JWT验证失败",
Data: nil,
})
return
}
// 验证是否过期
expirationTime, err := token.Claims.GetExpirationTime()
if err != nil {
s.resWriteJson(r, defaultHandlerResponse{
Status: 401,
Message: "JWT验证失败",
Data: nil,
})
return
}
if expirationTime.Before(time.Now()) {
s.resWriteJson(r, defaultHandlerResponse{
Status: 401,
Message: "JWT已过期",
Data: nil,
})
return
}
glog.Info(context.TODO(), "JWT验证通过")
// 验证通过,设置用户信息
audience, err := token.Claims.GetAudience()
if err != nil {
s.resWriteJson(r, defaultHandlerResponse{
Status: 401,
Message: "JWT验证失败",
Data: nil,
})
return
}
r.SetCtxVar("user_id", audience[0])
r.Middleware.Next()
}
// ResponseHandler is the middleware handling handler response object and its error. 中间件处理处理程序响应对象及其错误
func (s *sMiddleware) ResponseHandler(r *ghttp.Request) {
//defer action_log.NewActionLog().LogAdd(r) // 日志钩子
r.Middleware.Next()
// There's custom buffer content, it then exits current handler.
if r.Response.BufferLength() > 0 {
return
}
// 定义参数和类型.方便调用
var (
code int
msg string
resData = r.GetHandlerResponse() // 检索并返回处理程序响应对象及其错误
err = r.GetError() // 返回请求过程中发生的错误。如果没有错误,则返回 nil
errCode = gerror.Code(err) // 将错误信息通过接口解析处理
)
code = 200 // 默认返回状态码信息码
msg = "success" // 默认成功返回响应体文本信息
if err != nil {
code = 400 // 默认返回状态码信息码
switch errCode.Code() {
case -1:
msg = "Nonstandard error return"
resData = "I won't expose it to you. Go back and change it!"
case 500:
r.Response.Writer.Status = 500
return
default:
msg = errCode.Message()
resData = err.Error()
r.Response.Writer.Status = 400
if msg == "" || msg == "Unknown error reason" {
msg = "Nonstandard error return"
resData = "I won't expose it to you. Go back and change it!"
}
if resData == msg {
resData = ""
}
}
}
// 如果是空res返回则resData返回空字符串
if g.IsNil(resData) {
resData = ""
}
s.resWriteJson(r, defaultHandlerResponse{
Status: code,
Message: msg,
Data: resData,
})
}