You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

54 lines
1.5 KiB

3 years ago
  1. package middleware
  2. import (
  3. "context"
  4. "errors"
  5. "github.com/flipped-aurora/gin-vue-admin/server/global"
  6. "github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
  7. "github.com/gin-gonic/gin"
  8. "time"
  9. )
  10. // ip限制
  11. func IPLimit() gin.HandlerFunc {
  12. return func(c *gin.Context) {
  13. key := "RequestClientIPLimit===" + c.ClientIP()
  14. limit := global.GVA_CONFIG.System.LimitCountIP
  15. second := global.GVA_CONFIG.System.LimitTimeIP
  16. expiration := time.Duration(second) * time.Second
  17. if err := SetLimitWithTime(key, limit, expiration); err != nil {
  18. response.FailWithMessage(err.Error(), c)
  19. c.Abort()
  20. return
  21. }
  22. // 继续往下处理
  23. c.Next()
  24. }
  25. }
  26. // 设置访问次数
  27. func SetLimitWithTime(key string, limit int, expiration time.Duration) error {
  28. count, err := global.GVA_REDIS.Exists(context.Background(), key).Result()
  29. if err != nil || count == 0 {
  30. pipe := global.GVA_REDIS.TxPipeline()
  31. pipe.Incr(context.Background(), key)
  32. pipe.Expire(context.Background(), key, expiration)
  33. _, err := pipe.Exec(context.Background())
  34. return err
  35. } else {
  36. //次数
  37. if times, err := global.GVA_REDIS.Get(context.Background(), key).Int(); err != nil {
  38. return err
  39. } else {
  40. if times >= limit {
  41. if t, err := global.GVA_REDIS.PTTL(context.Background(), key).Result(); err != nil {
  42. return errors.New("请求太过频繁,请稍后再试")
  43. } else {
  44. return errors.New("请求太过频繁, 请 " + t.String() + " 秒后尝试")
  45. }
  46. } else {
  47. return global.GVA_REDIS.Incr(context.Background(), key).Err()
  48. }
  49. }
  50. }
  51. }