signature_interceptor.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. package rpc
  2. import (
  3. "context"
  4. "crypto/hmac"
  5. "crypto/sha256"
  6. "fmt"
  7. "google.golang.org/grpc"
  8. "google.golang.org/grpc/codes"
  9. "google.golang.org/grpc/metadata"
  10. "google.golang.org/grpc/status"
  11. "google.golang.org/protobuf/proto"
  12. "google.golang.org/protobuf/types/known/anypb"
  13. )
  14. // 自定义拦截器
  15. func SignatureInterceptor(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
  16. md, ok := metadata.FromIncomingContext(ctx)
  17. if !ok {
  18. return nil, status.Errorf(codes.InvalidArgument, "metadata is missing")
  19. }
  20. // 获取签名
  21. signature, ok := md["signature"]
  22. if !ok {
  23. return nil, status.Errorf(codes.Unauthenticated, "signature is missing")
  24. }
  25. // 验证签名
  26. if !verifySignature(req, signature[0]) {
  27. return nil, status.Errorf(codes.Unauthenticated, "invalid signature")
  28. }
  29. return handler(ctx, req)
  30. }
  31. // 验证签名
  32. func verifySignature(req interface{}, signature string) bool {
  33. // 假设req是*pb.HelloRequest
  34. message := req.(proto.Message)
  35. reqData, _ := anypb.New(message)
  36. reqBytes, _ := proto.Marshal(reqData)
  37. key := []byte("secret-key") // 秘钥应该保密
  38. mac := hmac.New(sha256.New, key)
  39. mac.Write(reqBytes)
  40. expectedSignature := fmt.Sprintf("%x", mac.Sum(nil))
  41. return expectedSignature == signature
  42. }