// Package middleware // @Link https://github.com/bufanyun/hotgo // @Copyright Copyright (c) 2023 HotGo CLI // @Author Ms <133814250@qq.com> // @License https://github.com/bufanyun/hotgo/blob/master/LICENSE package middleware import ( "context" "fmt" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gctx" "hotgo/internal/consts" "hotgo/internal/library/contexts" "hotgo/internal/library/token" "hotgo/internal/model" "hotgo/internal/service" "hotgo/utility/validate" "strings" "sync" ) type sMiddleware struct { LoginUrl string // 登录路由地址 NotRecordRequest g.Map // 不记录请求数据的路由(当前请求数据过大时会影响响应效率,可以将路径放到该选项中改善) FilterRoutes map[string]ghttp.RouterItem // 支持预处理的web路由 routeMutex sync.Mutex } func init() { service.RegisterMiddleware(NewMiddleware()) } func NewMiddleware() *sMiddleware { return &sMiddleware{ NotRecordRequest: g.Map{ "/api/goview/project/upload": struct{}{}, // 上传文件 }, } } // Ctx 初始化请求上下文 func (s *sMiddleware) Ctx(r *ghttp.Request) { data := make(g.Map) if _, ok := s.NotRecordRequest[r.URL.Path]; ok { data["request.body"] = gjson.New(nil) } else { data["request.body"] = gjson.New(r.GetBodyString()) } contexts.Init(r, &model.Context{ Data: data, Module: getModule(r.URL.Path), }) if len(r.Cookie.GetSessionId()) == 0 { r.Cookie.SetSessionId(gctx.CtxId(r.Context())) } r.Middleware.Next() } func getModule(path string) (module string) { slice := strings.Split(path, "/") if len(slice) < 2 { module = consts.AppDefault return } if slice[1] == "" { module = consts.AppDefault return } return slice[1] } // CORS allows Cross-origin resource sharing. func (s *sMiddleware) CORS(r *ghttp.Request) { r.Response.CORSDefault() r.Middleware.Next() } // DeliverUserContext 将用户信息传递到上下文中 func (s *sMiddleware) DeliverUserContext(r *ghttp.Request) (err error) { user, err := token.ParseLoginUser(r) if err != nil { return } switch user.App { case consts.AppAdmin: if err = service.AdminSite().BindUserContext(r.Context(), user); err != nil { return } default: contexts.SetUser(r.Context(), user) } return } // IsExceptAuth 是否是不需要验证权限的路由地址 func (s *sMiddleware) IsExceptAuth(ctx context.Context, appName, path string) bool { pathList := g.Cfg().MustGet(ctx, fmt.Sprintf("router.%v.exceptAuth", appName)).Strings() for i := 0; i < len(pathList); i++ { if validate.InSliceExistStr(pathList[i], path) { return true } } return false } // IsExceptLogin 是否是不需要登录的路由地址 func (s *sMiddleware) IsExceptLogin(ctx context.Context, appName, path string) bool { pathList := g.Cfg().MustGet(ctx, fmt.Sprintf("router.%v.exceptLogin", appName)).Strings() for i := 0; i < len(pathList); i++ { if validate.InSliceExistStr(pathList[i], path) { return true } } return false }