package interceptors import ( "context" "fmt" "strings" "gitea.badhouseplants.net/softplayer/softplayer-backend/internal/tools/logger" "github.com/golang-jwt/jwt/v5" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) type JWTVerifier struct { secret []byte serverCtx context.Context } func NewJWTVerifier(ctx context.Context, secret []byte) *JWTVerifier { return &JWTVerifier{ serverCtx: ctx, secret: secret, } } // This is an interceptors that should verify that a user is authorized func (v *JWTVerifier) JWTAuthInterceptor( ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, ) (interface{}, error) { log := logger.FromContext(v.serverCtx).WithValues("method", info.FullMethod) if !strings.Contains(info.FullMethod, "NoAuth") { log.Info("Checking the JWT token") md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil, status.Error(codes.Unauthenticated, "User is not authorized") } tokenString := md.Get("token")[0] token, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) { // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key") return v.secret, nil }, jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Alg()})) if err != nil { return nil, status.Error(codes.Unauthenticated, "User is not authorized") } if claims, ok := token.Claims.(jwt.MapClaims); ok { fmt.Println(claims["userID"]) } else { fmt.Println(err) } // Get the token from the metadata // Validate the token // Get the user id from the token } else { log.Info("Auth is not required for this request") } return handler(ctx, req) }