grpc / grpc-node

gRPC for Node.js
https://grpc.io
Apache License 2.0
4.48k stars 649 forks source link

JWT token Authorization key usage issue while adding it in metadata #2614

Closed vamsideepak closed 11 months ago

vamsideepak commented 1 year ago

Problem description

issue 1:

generateJWToken(){
    const token = jwt.sign({}, this.JWTsignatureKey, { expiresIn: '5h' });
    console.log('JWT Token', token);
     this.metadata = new this.electronService.grpc.Metadata();
     this.metadata.add('Authorization', `Bearer ${token}`);
     console.log('JWT Metadata', this.metadata);
  }

when I add this code and console it then Authorization key is changing into authorization because this token verification is failing on the sevrer and grpc connection is not established.

Issue 2: How we can send metadata in streaming methods , I am trying in the below way . is this correct ?

const GrpcPmTransStream = this.pmTransactionClient.Subscribe(randomUUID, this.metadata);

Environment

How can we resolve this ?

murgatroid99 commented 1 year ago

The problem is not the case of the metadata key. gRPC only supports lower-case metadata keys, so metadata keys are automatically converted to lower case.

If the connection is actually not established, that is a different problem, because connections are fully established before any metadata is even sent. If you provide more information about the connection error you are seeing, we can get a better idea of what is going wrong.

The way you are sending the metadata looks correct. Once you fix the connection errors, you should be able to check whether the metadata is present on the server.

vamsideepak commented 1 year ago

@murgatroid99
I am running one exe file consist of grpc server (which is implemented in .Net ) and I am trying to connect with the server using createSSL() method(server url as localhost:5002) and I have imported the SSL certificate in my local system(windows 11) as well.

After all the setup when I run the exe through my code I am getting the below error and my exe application is closing itself but the same exe application working fine(running idly when I ran it manually)

example code:

const sslCreds = this.electronService.grpc.credentials.createSsl();
 this.pmTransactionClient = new this.pmTransactionPackage.GrpcEpmTransactionService(this.periPheralPort, sslCreds )
 const GrpcPmTransStream = this.pmTransactionClient.Subscribe(randomUUID, this.metadata);
  GrpcPmTransStream.on('data', (response) => {})
  GrpcPmTransStream.on('end', (error) => {})
GrpcPmTransStream.on('error', (error) => {})

error : "14 UNAVAILABLE: No connection established. Last error: connect ECONNREFUSED 127.0.0.1:5002 (2023-11-13T18:19:09.073Z)"

"Error: 14 UNAVAILABLE: No connection established. Last error: connect ECONNREFUSED 127.0.0.1:5002 (2023-11-13T18:19:09.073Z)
    at callErrorFromStatus (C:\Users\xxx\Desktop\MockServer\Trilogy_Client_Installer\node_modules\@grpc\grpc-js\build\src\call.js:31:19)
    at Object.onReceiveStatus (C:\Users\xxx\Desktop\MockServer\Trilogy_Client_Installer\node_modules\@grpc\grpc-js\build\src\client.js:357:73)
    at Object.onReceiveStatus (C:\Users\xxx\Desktop\MockServer\Trilogy_Client_Installer\node_modules\@grpc\grpc-js\build\src\client-interceptors.js:323:181)
    at C:\Users\xxxDesktop\MockServer\Trilogy_Client_Installer\node_modules\@grpc\grpc-js\build\src\resolving-call.js:99:78
    at processTicksAndRejections (node:internal/process/task_queues:77:11)
    at runNextTicks (node:internal/process/task_queues:64:3)
    at process.processImmediate (node:internal/timers:447:9)
for call at
    at ServiceClientImpl.makeServerStreamRequest (C:\Users\xxx\Desktop\MockServer\Trilogy_Client_Installer\node_modules\@grpc\grpc-js\build\src\client.js:340:32)
    at ServiceClientImpl.<anonymous> (C:\Users\xxx\Desktop\MockServer\Trilogy_Client_Installer\node_modules\@grpc\grpc-js\build\src\make-client.js:105:19)
    at t.clientGrpcPmTrans (http://localhost:4200/main.js:1:380780)
    at http://localhost:4200/main.js:1:377600
    at Generator.next (<anonymous>)
    at W2 (http://localhost:4200/main.js:1:330951)
    at c (http://localhost:4200/main.js:1:331154)
    at http://localhost:4200/main.js:1:331215
    at new d (http://localhost:4200/polyfills.js:1:19228)
    at http://localhost:4200/main.js:1:331095
    at ge.<computed> (http://localhost:4200/polyfills.js:1:29345)
    at B.invokeTask (http://localhost:4200/polyfills.js:1:7845)
    at T.runTask (http://localhost:4200/polyfills.js:1:3210)
    at invokeTask (http://localhost:4200/polyfills.js:1:8899)
    at invoke (http://localhost:4200/polyfills.js:1:8800)
    at U.z.args.<computed> (http://localhost:4200/polyfills.js:1:29047)"

Can you help me please

murgatroid99 commented 1 year ago

The ECONNREFUSED error suggests that there isn't actually a server listening on that port. I suggest verifying that first. Are you able to connect to that server with any other client?

vamsideepak commented 1 year ago

@murgatroid99

image

I am able to listen the events from the postman. my postman server url will be look like this : grpc://localhost:5002 I tried adding the grpc://localhost:5002 , dns://localhost:5002, https://localhost:5002, 127.0.01:5002 but still no luck.

another question if I mentioned as localhost then grpc internally changing it into 127.0.0.1 ??

murgatroid99 commented 1 year ago

Just to check, are you running the client on the same machine that the server is running on? Are there any docker containers involved in your setup? I can't think of anything else, you'll need to debug the connectivity issue on your own.

localhost is a name, which refers to the machine that the code is running on. 127.0.0.1 is the IP address of the machine that the code is running on, specifically the IPv4 address. There is also an IPv6 address with the same meaning, ::1. localhost can refer to either or both of those IP addresses, so it is convenient to use that name any time you want to connect to an open port on the local computer, but the actual network communication uses the IP address.

vamsideepak commented 11 months ago

@murgatroid99 it is my SSL certification issue and that it not allowing to make connection . I have tested the SSL through _openssl sclient -connect localhost:5002 command and it has give lot of information about handshaking with server cert.

But I have a question how client will bypass or override the ssl when server is using SSL certificates. I have tried the below configurations but no luck

       const clientOptions = {
      'grpc.ssl_target_name_override': 'localhost',
       'grpc.default_authority': 'localhost',
       };
       const sslCreds = this.electronService.grpc.credentials.createSsl();
       this.scannerClient = new this.scannerPackage.GrpcPmScannerService(this.periPheralPort, clientOptions);
murgatroid99 commented 11 months ago

The proper usage of those options is to have the server use the real certificate for the domain you will be serving from, and for the client to act as though it is connecting to that domain when validating the certificate. For example, if your actual website is example.com, the server should use a certificate for example.com and both of those client options should be set to the value example.com.