servicecontext.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package svc
  2. import (
  3. "perms-system-server/internal/config"
  4. "perms-system-server/internal/loaders"
  5. "perms-system-server/internal/middleware"
  6. "perms-system-server/internal/model"
  7. "github.com/zeromicro/go-zero/core/limit"
  8. "github.com/zeromicro/go-zero/core/stores/redis"
  9. "github.com/zeromicro/go-zero/core/stores/sqlx"
  10. "github.com/zeromicro/go-zero/rest"
  11. )
  12. type ServiceContext struct {
  13. Config config.Config
  14. JwtAuth rest.Middleware
  15. ProductLoginRateLimit rest.Middleware
  16. AdminLoginRateLimit rest.Middleware
  17. SyncRateLimit rest.Middleware
  18. RefreshTokenRateLimit rest.Middleware
  19. GrpcLoginLimiter *limit.PeriodLimit
  20. GrpcRefreshLimiter *limit.PeriodLimit
  21. GrpcVerifyLimiter *limit.PeriodLimit
  22. UsernameLoginLimit *limit.PeriodLimit
  23. TokenOpLimiter *limit.PeriodLimit
  24. UserDetailsLoader *loaders.UserDetailsLoader
  25. *model.Models
  26. }
  27. func NewServiceContext(c config.Config) *ServiceContext {
  28. conn := sqlx.NewMysql(c.MySQL.DataSource)
  29. rds := redis.MustNewRedis(c.CacheRedis.Nodes[0].RedisConf)
  30. models := model.NewModels(conn, c.CacheRedis.Nodes, c.CacheRedis.KeyPrefix)
  31. udLoader := loaders.NewUserDetailsLoader(rds, c.CacheRedis.KeyPrefix, models)
  32. productLoginRL := middleware.NewRateLimitMiddleware(rds, 60, 30, c.CacheRedis.KeyPrefix+":rl:login:product", c.BehindProxy)
  33. adminLoginRL := middleware.NewRateLimitMiddleware(rds, 60, 20, c.CacheRedis.KeyPrefix+":rl:login:admin", c.BehindProxy)
  34. syncRlMiddleware := middleware.NewRateLimitMiddleware(rds, 60, 10, c.CacheRedis.KeyPrefix+":rl:sync", c.BehindProxy)
  35. refreshTokenRL := middleware.NewRateLimitMiddleware(rds, 60, 30, c.CacheRedis.KeyPrefix+":rl:refresh", c.BehindProxy)
  36. grpcLimiter := limit.NewPeriodLimit(60, 20, rds, c.CacheRedis.KeyPrefix+":rl:grpc:login")
  37. // gRPC refreshToken 一般低频操作(分钟级),限紧一点可以同时防签名爆破与并发刷新被用作会话劫持的放大器。
  38. grpcRefreshLimiter := limit.NewPeriodLimit(60, 30, rds, c.CacheRedis.KeyPrefix+":rl:grpc:refresh")
  39. // gRPC verifyToken 是下游每请求都会调用的热路径,阈值必须足够高;这里的作用是兜底防止下游被攻破后把权限中心当 token oracle 爆破。
  40. grpcVerifyLimiter := limit.NewPeriodLimit(60, 6000, rds, c.CacheRedis.KeyPrefix+":rl:grpc:verify")
  41. usernameLimiter := limit.NewPeriodLimit(300, 10, rds, c.CacheRedis.KeyPrefix+":rl:user")
  42. tokenOpLimiter := limit.NewPeriodLimit(60, 10, rds, c.CacheRedis.KeyPrefix+":rl:tokenop")
  43. return &ServiceContext{
  44. Config: c,
  45. JwtAuth: middleware.NewJwtAuthMiddleware(c.Auth.AccessSecret, udLoader).Handle,
  46. ProductLoginRateLimit: productLoginRL.Handle,
  47. AdminLoginRateLimit: adminLoginRL.Handle,
  48. SyncRateLimit: syncRlMiddleware.Handle,
  49. RefreshTokenRateLimit: refreshTokenRL.Handle,
  50. GrpcLoginLimiter: grpcLimiter,
  51. GrpcRefreshLimiter: grpcRefreshLimiter,
  52. GrpcVerifyLimiter: grpcVerifyLimiter,
  53. UsernameLoginLimit: usernameLimiter,
  54. TokenOpLimiter: tokenOpLimiter,
  55. UserDetailsLoader: udLoader,
  56. Models: models,
  57. }
  58. }