1
0

server.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package micro
  2. import (
  3. "context"
  4. "dashoo.cn/micro_libary/gtoken"
  5. "github.com/gogf/gf/v2/errors/gerror"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. "github.com/gogf/gf/v2/text/gstr"
  9. "github.com/rcrowley/go-metrics"
  10. "github.com/rpcxio/rpcx-consul/serverplugin"
  11. "github.com/smallnest/rpcx/protocol"
  12. "github.com/smallnest/rpcx/server"
  13. "github.com/smallnest/rpcx/share"
  14. "strings"
  15. "time"
  16. )
  17. const Tenant = "Tenant"
  18. func CreateAndInitService(basePath string) *server.Server {
  19. var ctx = gctx.New()
  20. bindAddr, _ := g.Config().Get(ctx, "setting.bind-addr")
  21. registryType, _ := g.Config().Get(ctx, "setting.registry-type")
  22. registryAddr, _ := g.Config().Get(ctx, "setting.registry-addr")
  23. s := server.NewServer()
  24. g.Log().Infof(context.Background(), "服务启动, BindName: %v, BindAddr: %s", basePath, bindAddr.String())
  25. if registryType.String() == "consul" {
  26. addConsulRegistryPlugin(ctx, s, basePath, bindAddr.String(), registryAddr.String())
  27. }
  28. return s
  29. }
  30. func addConsulRegistryPlugin(ctx context.Context, s *server.Server, basePath, srvAddr, consulAddr string) {
  31. r := &serverplugin.ConsulRegisterPlugin{
  32. ServiceAddress: "tcp@" + srvAddr,
  33. ConsulServers: []string{consulAddr},
  34. BasePath: basePath,
  35. Metrics: metrics.NewRegistry(),
  36. UpdateInterval: time.Minute,
  37. }
  38. err := r.Start()
  39. if err != nil {
  40. g.Log().Fatal(ctx, err)
  41. }
  42. g.Log().Infof(ctx, "注册到Consul: %v, basePath: %v, MicorSrv: %v", consulAddr, basePath, srvAddr)
  43. s.Plugins.Add(r)
  44. }
  45. // HandleAuth 处理身份验证
  46. func HandleAuth(ctx context.Context, req *protocol.Message, token string, authExcludePaths []string) error {
  47. tenant := getTenant(req)
  48. g.Log().Infof(ctx, " ServicePath: %s, ServiceMethod: %s,Tenant:%s", req.ServicePath, req.ServiceMethod, tenant)
  49. reqPath := "/" + req.ServicePath + "/" + req.ServiceMethod
  50. if authPath(reqPath, authExcludePaths) {
  51. req.Metadata["authExclude"] = "false"
  52. var rsp gtoken.Resp
  53. notAuthSrv := ctx.Value("NotAuthSrv")
  54. if notAuthSrv != nil && notAuthSrv.(bool) {
  55. rsp = gtoken.GFToken.ValidToken(ctx, token)
  56. } else {
  57. ctx = context.WithValue(ctx, share.ReqMetaDataKey, map[string]string{"tenant": tenant})
  58. rsp = validToken(ctx, token)
  59. }
  60. if rsp.Code != 0 && rsp.Code != 200 {
  61. return gerror.New("Token 认证失败!")
  62. }
  63. if req.Metadata != nil {
  64. req.Metadata["userInfo"] = rsp.DataString()
  65. }
  66. return nil
  67. }
  68. return nil
  69. }
  70. // 判断路径是否需要进行认证拦截
  71. // return true 需要认证
  72. func authPath(urlPath string, authExcludePaths []string) bool {
  73. // 去除后斜杠
  74. if strings.HasSuffix(urlPath, "/") {
  75. urlPath = gstr.SubStr(urlPath, 0, len(urlPath)-1)
  76. }
  77. // 排除路径处理,到这里nextFlag为true
  78. for _, excludePath := range authExcludePaths {
  79. tmpPath := excludePath
  80. // 前缀匹配
  81. if strings.HasSuffix(tmpPath, "/*") {
  82. tmpPath = gstr.SubStr(tmpPath, 0, len(tmpPath)-2)
  83. if gstr.HasPrefix(urlPath, tmpPath) {
  84. // 前缀匹配不拦截
  85. return false
  86. }
  87. } else {
  88. // 全路径匹配
  89. if strings.HasSuffix(tmpPath, "/") {
  90. tmpPath = gstr.SubStr(tmpPath, 0, len(tmpPath)-1)
  91. }
  92. if urlPath == tmpPath {
  93. // 全路径匹配不拦截
  94. return false
  95. }
  96. }
  97. }
  98. return true
  99. }
  100. // 验证token
  101. func validToken(ctx context.Context, token string) gtoken.Resp {
  102. grsp := gtoken.Resp{}
  103. if token == "" {
  104. grsp.Code = 401
  105. grsp.Msg = "valid token empty"
  106. return grsp
  107. }
  108. authService := InitMicroSrvClient(ctx, "Auth", "micro_srv.auth")
  109. defer authService.Close()
  110. rsp := &gtoken.Resp{}
  111. err := authService.Call(ctx, "ValidToken", token, rsp)
  112. if err != nil {
  113. g.Log().Error(ctx, err)
  114. grsp.Code = 401
  115. return grsp
  116. }
  117. grsp.Code = int(rsp.Code)
  118. grsp.Msg = rsp.Msg
  119. grsp.Data = rsp.Data
  120. return grsp
  121. }
  122. func getTenant(msg *protocol.Message) string {
  123. var tenant string
  124. if msg.Metadata != nil {
  125. tenant = msg.Metadata[Tenant]
  126. }
  127. return tenant
  128. }