middleware.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. package router
  2. import (
  3. "context"
  4. "errors"
  5. "net/http"
  6. "time"
  7. "github.com/gin-gonic/gin"
  8. "github.com/go-redis/redis/v8"
  9. jsoniter "github.com/json-iterator/go"
  10. mhayaTime "github.com/mhaya/extend/time"
  11. cfacade "github.com/mhaya/facade"
  12. "github.com/mhaya/game/game_cluster/internal/code"
  13. "github.com/mhaya/game/game_cluster/internal/constant"
  14. "github.com/mhaya/game/game_cluster/internal/mdb"
  15. "github.com/mhaya/game/game_cluster/internal/mdb/eventmodels"
  16. "github.com/mhaya/game/game_cluster/internal/mdb/models"
  17. "github.com/mhaya/game/game_cluster/internal/param"
  18. rpcLogstash "github.com/mhaya/game/game_cluster/internal/rpc/logstash"
  19. "github.com/mhaya/game/game_cluster/nodes/webadmin/common"
  20. mhayaLogger "github.com/mhaya/logger"
  21. "go.mongodb.org/mongo-driver/bson"
  22. "go.mongodb.org/mongo-driver/mongo"
  23. )
  24. var (
  25. json = jsoniter.ConfigCompatibleWithStandardLibrary
  26. )
  27. func Auth(app cfacade.IApplication) gin.HandlerFunc {
  28. return func(c *gin.Context) {
  29. // 请求开始时间
  30. startTime := mhayaTime.Now().UnixMilli()
  31. tokenString := ""
  32. roleId := ""
  33. var err error
  34. defer func() {
  35. sendLogRecord(c, app, tokenString, roleId, startTime)
  36. }()
  37. tokenString = c.GetHeader("Token")
  38. if tokenString == "" {
  39. common.PackUnauthorizedResult(c, code.UnauthorizedError, "token is empty")
  40. return
  41. }
  42. roleId, err = mdb.RDB.Get(context.Background(), tokenString).Result()
  43. if err != nil && err != redis.Nil {
  44. mhayaLogger.Warnf("Auth Get error: %s", err.Error())
  45. common.PackUnauthorizedResult(c, code.InternalError, "token is empty")
  46. return
  47. }
  48. if roleId == "" {
  49. common.PackUnauthorizedResult(c, code.UnauthorizedError, "token is invalid")
  50. return
  51. }
  52. if roleId != constant.AdminAccess {
  53. urlAccess, err := mdb.RDB.HGet(context.Background(), common.GetTokenKey(tokenString), c.Request.URL.Path).Result()
  54. if err != nil {
  55. mhayaLogger.Warnf("Auth HGet s error: %s", err.Error())
  56. common.PackUnauthorizedResult(c, code.InternalError, "")
  57. return
  58. }
  59. // 检查url权限
  60. if urlAccess == "" {
  61. common.PackUnauthorizedResult(c, code.UnauthorizedError, "token is no auth")
  62. return
  63. }
  64. // 非管理员需要进行ip校验
  65. openIpWhitelist := app.Settings().Get("open_ip_whitelist").ToBool()
  66. if openIpWhitelist {
  67. err = checkIPWhitelist(c)
  68. if err != nil {
  69. mhayaLogger.Warnf("Auth checkIPWhitelist error: %s", err.Error())
  70. common.PackForbiddenResult(c, code.ForbiddenError, "ip is no auth")
  71. return
  72. }
  73. }
  74. }
  75. adminAccess, err := mdb.RDB.HGet(context.Background(), common.GetTokenKey(tokenString), constant.AdminAccess).Result()
  76. if err != nil {
  77. mhayaLogger.Warnf("Auth HGet ss error: %s", err.Error())
  78. common.PackUnauthorizedResult(c, code.InternalError, "")
  79. return
  80. }
  81. // 检查管理员权限
  82. if adminAccess == "" {
  83. common.PackUnauthorizedResult(c, code.UnauthorizedError, "token is no auth")
  84. return
  85. }
  86. c.Next()
  87. }
  88. }
  89. // checkIP
  90. func checkIPWhitelist(c *gin.Context) error {
  91. // 获取请求的ip
  92. ip := c.ClientIP()
  93. var whitelistModel *models.Whitelist
  94. collection := mdb.MDB.Collection(whitelistModel.TableName())
  95. // 设置超时时间
  96. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  97. defer cancel() // 确保在函数退出时取消上下文
  98. // 示例:查询 IP 是否在白名单中
  99. err := collection.FindOne(ctx, bson.M{"ip": ip}).Decode(&whitelistModel)
  100. if err != nil && err != mongo.ErrNoDocuments {
  101. return err
  102. }
  103. // 根据查询结果决定是否允许访问
  104. if whitelistModel == nil {
  105. return errors.New("IP not in whitelist") // 拒绝访问
  106. }
  107. return nil // 允许访问
  108. }
  109. func sendLogRecord(c *gin.Context, app cfacade.IApplication, tokenString, roleId string, startTime int64) {
  110. userName, err := mdb.RDB.Get(context.Background(), common.GetUserNameKey(tokenString)).Result()
  111. if err != nil {
  112. mhayaLogger.Warnf("sendLogRecord Get userName error: %s, token: %s", err.Error(), tokenString)
  113. return
  114. }
  115. nodeId := app.NodeId()
  116. req, err := packBackendOperationEventReq(nodeId, &eventmodels.BackendOperationEventContent{
  117. UserBasic: eventmodels.UserBasic{
  118. UserName: userName,
  119. IsRobot: false,
  120. },
  121. EventBasic: eventmodels.EventBasic{
  122. ServerId: nodeId,
  123. IsSuccess: func() bool {
  124. return c.Writer.Status() == http.StatusOK
  125. }(),
  126. CreateAt: mhayaTime.Now().Unix(),
  127. },
  128. RoleId: roleId,
  129. Path: c.Request.URL.Path,
  130. Method: c.Request.Method,
  131. StatusCode: c.Writer.Status(),
  132. Dur: mhayaTime.Now().UnixMilli() - startTime,
  133. ClientIP: c.ClientIP(),
  134. ErrorMessage: c.Errors.ByType(gin.ErrorTypePrivate).String(),
  135. })
  136. if err != nil {
  137. mhayaLogger.Warnf("sendLogRecord packBackendOperationEventReq error: %s, token: %s", err.Error(), tokenString)
  138. return
  139. }
  140. rpcLogstash.HandleLogRecord(app, req)
  141. }
  142. func packBackendOperationEventReq(nodeId string, content *eventmodels.BackendOperationEventContent) (*param.HandleLogReq, error) {
  143. bytes, err := json.Marshal(content)
  144. if err != nil {
  145. return nil, err
  146. }
  147. return &param.HandleLogReq{
  148. ServerId: nodeId,
  149. EventName: content.EventName(),
  150. JsonContent: string(bytes),
  151. }, nil
  152. }