golang-im聊天
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

93 řádky
2.9 KiB

  1. package interceptor
  2. import (
  3. "context"
  4. "gim/pkg/gerrors"
  5. "gim/pkg/grpclib"
  6. "gim/pkg/logger"
  7. "gim/pkg/pb"
  8. "gim/pkg/rpc"
  9. "strings"
  10. "go.uber.org/zap"
  11. "google.golang.org/grpc"
  12. "google.golang.org/grpc/metadata"
  13. "google.golang.org/grpc/status"
  14. )
  15. // NewInterceptor 生成GRPC过滤器
  16. func NewInterceptor(name string, urlWhitelist map[string]int) grpc.UnaryServerInterceptor {
  17. return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
  18. defer gerrors.LogPanic(name, ctx, req, info, &err)
  19. md, _ := metadata.FromIncomingContext(ctx)
  20. err = handleMasterAuth(ctx, req, info, handler)
  21. logger.Logger.Debug(name, zap.Any("method", info.FullMethod), zap.Any("md", md), zap.Any("req", req),
  22. zap.Any("resp", resp), zap.Error(err))
  23. s, _ := status.FromError(err)
  24. if s.Code() != 0 && s.Code() < 1000 {
  25. md, _ := metadata.FromIncomingContext(ctx)
  26. logger.Logger.Error(name, zap.String("method", info.FullMethod), zap.Any("md", md), zap.Any("req", req),
  27. zap.Any("resp", resp), zap.Error(err), zap.String("stack", gerrors.GetErrorStack(s)))
  28. }
  29. if err != nil {
  30. return
  31. }
  32. resp, err = handleWithAuth(ctx, req, info, handler, urlWhitelist)
  33. logger.Logger.Debug(name, zap.Any("method", info.FullMethod), zap.Any("md", md), zap.Any("req", req),
  34. zap.Any("resp", resp), zap.Error(err))
  35. s, _ = status.FromError(err)
  36. if s.Code() != 0 && s.Code() < 1000 {
  37. md, _ := metadata.FromIncomingContext(ctx)
  38. logger.Logger.Error(name, zap.String("method", info.FullMethod), zap.Any("md", md), zap.Any("req", req),
  39. zap.Any("resp", resp), zap.Error(err), zap.String("stack", gerrors.GetErrorStack(s)))
  40. }
  41. return
  42. }
  43. }
  44. // handleWithAuth 处理鉴权逻辑
  45. func handleWithAuth(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, urlWhitelist map[string]int) (interface{}, error) {
  46. serverName := strings.Split(info.FullMethod, "/")[1]
  47. if !strings.HasSuffix(serverName, "Int") {
  48. if _, ok := urlWhitelist[info.FullMethod]; !ok {
  49. userId, deviceId, err := grpclib.GetCtxData(ctx)
  50. if err != nil {
  51. return nil, err
  52. }
  53. token, err := grpclib.GetCtxToken(ctx)
  54. if err != nil {
  55. return nil, err
  56. }
  57. _, err = rpc.GetBusinessIntClient().Auth(ctx, &pb.AuthReq{
  58. UserId: userId,
  59. DeviceId: deviceId,
  60. Token: token,
  61. })
  62. if err != nil {
  63. return nil, err
  64. }
  65. }
  66. }
  67. return handler(ctx, req)
  68. }
  69. // handleMasterAuth 处理站长权限
  70. func handleMasterAuth(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) error {
  71. serverName := strings.Split(info.FullMethod, "/")[1]
  72. if !strings.HasSuffix(serverName, "Int") {
  73. masterId, err := grpclib.GetCtxMasterId(ctx)
  74. _, err = rpc.GetBusinessIntClient().MasterAuth(ctx, &pb.MasterAuthReq{MasterId: masterId})
  75. if err != nil {
  76. return err
  77. }
  78. }
  79. return nil
  80. }