package micro import ( "context" "dashoo.cn/micro_libary/myerrors" "github.com/gogf/gf/v2/encoding/gbase64" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gctx" "github.com/rcrowley/go-metrics" "github.com/rpcxio/rpcx-consul/serverplugin" "github.com/smallnest/rpcx/server" "github.com/smallnest/rpcx/share" "time" ) const Tenant = "Tenant" func CreateAndInitService(basePath string) *server.Server { var ctx = gctx.New() bindAddr, _ := g.Config().Get(ctx, "setting.bind-addr") registryType, _ := g.Config().Get(ctx, "setting.registry-type") registryAddr, _ := g.Config().Get(ctx, "setting.registry-addr") s := server.NewServer() g.Log().Infof(context.Background(), "服务启动, BindName: %v, BindAddr: %s", basePath, bindAddr.String()) if registryType.String() == "consul" { addConsulRegistryPlugin(ctx, s, basePath, bindAddr.String(), registryAddr.String()) } return s } func addConsulRegistryPlugin(ctx context.Context, s *server.Server, basePath, srvAddr, consulAddr string) { r := &serverplugin.ConsulRegisterPlugin{ ServiceAddress: "tcp@" + srvAddr, ConsulServers: []string{consulAddr}, BasePath: basePath, Metrics: metrics.NewRegistry(), UpdateInterval: time.Minute, } err := r.Start() if err != nil { g.Log().Fatal(ctx, err) } g.Log().Infof(ctx, "注册到Consul: %v, basePath: %v, MicorSrv: %v", consulAddr, basePath, srvAddr) s.Plugins.Add(r) } //// HandleAuth 处理身份验证 //func HandleAuth(ctx context.Context, req *protocol.Message, token string, authExcludePaths []string) error { // tenant := getTenant(req) // g.Log().Infof(ctx, " ServicePath: %s, ServiceMethod: %s,Tenant:%s", req.ServicePath, req.ServiceMethod, tenant) // // reqPath := "/" + req.ServicePath + "/" + req.ServiceMethod // if authPath(reqPath, authExcludePaths) { // req.Metadata["authExclude"] = "false" // var rsp gtoken.Resp // notAuthSrv := ctx.Value("NotAuthSrv") // if notAuthSrv != nil && notAuthSrv.(bool) { // rsp = gtoken.GFToken.ValidToken(ctx, token) // } else { // ctx = context.WithValue(ctx, share.ReqMetaDataKey, map[string]string{"tenant": tenant}) // rsp = validToken(ctx, token) // } // // if rsp.Code != 0 && rsp.Code != 200 { // return gerror.New("Token 认证失败!") // } // if req.Metadata != nil { // req.Metadata["userInfo"] = rsp.DataString() // } // return nil // } // return nil //} // //// 判断路径是否需要进行认证拦截 //// return true 需要认证 //func authPath(urlPath string, authExcludePaths []string) bool { // // 去除后斜杠 // if strings.HasSuffix(urlPath, "/") { // urlPath = gstr.SubStr(urlPath, 0, len(urlPath)-1) // } // // // 排除路径处理,到这里nextFlag为true // for _, excludePath := range authExcludePaths { // tmpPath := excludePath // // 前缀匹配 // if strings.HasSuffix(tmpPath, "/*") { // tmpPath = gstr.SubStr(tmpPath, 0, len(tmpPath)-2) // if gstr.HasPrefix(urlPath, tmpPath) { // // 前缀匹配不拦截 // return false // } // } else { // // 全路径匹配 // if strings.HasSuffix(tmpPath, "/") { // tmpPath = gstr.SubStr(tmpPath, 0, len(tmpPath)-1) // } // if urlPath == tmpPath { // // 全路径匹配不拦截 // return false // } // } // } // return true //} // //// 验证token //func validToken(ctx context.Context, token string) gtoken.Resp { // grsp := gtoken.Resp{} // if token == "" { // grsp.Code = 401 // grsp.Msg = "valid token empty" // return grsp // } // // authService := InitMicroSrvClient(ctx, "Auth", "micro_srv.auth") // defer authService.Close() // rsp := >oken.Resp{} // err := authService.Call(ctx, "ValidToken", token, rsp) // if err != nil { // g.Log().Error(ctx, err) // grsp.Code = 401 // return grsp // } // grsp.Code = int(rsp.Code) // grsp.Msg = rsp.Msg // grsp.Data = rsp.Data // return grsp //} // //func getTenant(msg *protocol.Message) string { // var tenant string // if msg.Metadata != nil { // tenant = msg.Metadata[Tenant] // } // return tenant //} // GetTenant 从context中获取租户码 func GetTenant(ctx context.Context) (string, error) { reqMeta := ctx.Value(share.ReqMetaDataKey).(map[string]string) tenant, ok := reqMeta["tenant"] if !ok { return "", myerrors.TipsError("不存在租户码") } return tenant, nil } // IsAuthExclude 是否进行auth验证 func IsAuthExclude(ctx context.Context) bool { reqMeta := ctx.Value(share.ReqMetaDataKey).(map[string]string) flag, ok := reqMeta["authExclude"] if !ok || flag == "true" { return true } return false } // GetUserInfo 从context中获取UserInfo func GetUserInfo(ctx context.Context) (UserInfo, error) { reqMeta := ctx.Value(share.ReqMetaDataKey).(map[string]string) userStr, ok := reqMeta["userInfo"] if !ok { return UserInfo{}, myerrors.TipsError("用户信息获取失败,请重新登录。") } userInfo, err := getUserInfoDataString(ctx, userStr) if err != nil { return UserInfo{}, myerrors.TipsError("用户信息解码失败。") } return userInfo, nil } // getUserInfoDataString 从userInfo字符串转换成对象 func getUserInfoDataString(ctx context.Context, userInfoString string) (UserInfo, error) { var userInfo UserInfo //uuid := "" if j, err := gjson.DecodeToJson(userInfoString); err != nil { g.Log().Error(ctx, err) return userInfo, err } else { j.SetViolenceCheck(true) err = j.Scan(&userInfo) if err != nil { g.Log().Error(ctx, err) return userInfo, err } } return userInfo, nil } // GetBrowserInfo 从context中获取ClientIP和UserAgent func GetBrowserInfo(ctx context.Context) (clientIP string, userAgent string, err error) { reqMeta := ctx.Value(share.ReqMetaDataKey).(map[string]string) clientIP, ok := reqMeta["clientIP"] if !ok { return "", "", myerrors.TipsError("BrowserInfo获取失败") } userAgent, ok = reqMeta["userAgent"] if !ok { return "", "", myerrors.TipsError("BrowserInfo获取失败") } userAgent, err = gbase64.DecodeToString(userAgent) return }