title: How to create JWT for Google service account using Node.js?
body: <p>According to this <a href="https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth" rel="nofollow noreferrer">guide</a> i have successfully create JWT for Google service account using Java example and it's worked. However, these lines are still "magical" for me:</p>
  
  <pre><code>GoogleCredential credential = GoogleCredential.fromStream(resourceAsStream);
  PrivateKey privateKey = credential.getServiceAccountPrivateKey();
  </code></pre>
  
  <p>But i can't repeat it using Node.js. Postman says "Could not get any response".</p>
  
  <p>Here is my code.</p>
  
  <pre><code>const jwt = require('jsonwebtoken');
  
  const TOKEN_DURATION_IN_SECONDS = 3600;
  
  const issueJWT = (
    issuedAt = Math.floor(Date.now() / 1000),
    serviceAccount = require('path/to/service-account.json')
  ) =&gt;
    jwt.sign(
      {
        'iss': serviceAccount.client_email,
        'sub': serviceAccount.client_email,
        'aud': `https://${SERVICE_NAME}/${API_NAME}`,
        'iat': issuedAt,
        'exp': issuedAt + TOKEN_DURATION_IN_SECONDS,
      },
      serviceAccount.private_key,
      {
        algorithm: 'RS256',
        header: {
          'kid': serviceAccount.private_key_id,
          'typ': 'JWT',
          'alg': 'RS256',
        },
      }
    );
  </code></pre>
  
  <p><a href="http://calebb.net/" rel="nofollow noreferrer">Onlinde decoder</a> show same header and body for tokens created using Node.js and Java.</p>
  
  <p>So, i assume that signatures are different.</p>
  
  <p>Via jwt from java:</p>
  
  <pre><code>curl --header "Authorization: Bearer {jwt-from-java}" https://bigtableadmin.googleapis.com/v2/projects/{project-name}/instances -v
  &gt;
  * schannel: client wants to read 102400 bytes
  * schannel: encdata_buffer resized 103424
  * schannel: encrypted data buffer: offset 0 length 103424
  * schannel: encrypted data got 836
  * schannel: encrypted data buffer: offset 836 length 103424
  * schannel: decrypted data length: 773
  * schannel: decrypted data added: 773
  * schannel: decrypted data cached: offset 773 length 102400
  * schannel: encrypted data length: 34
  * schannel: encrypted data cached: offset 34 length 103424
  * schannel: decrypted data length: 5
  * schannel: decrypted data added: 5
  * schannel: decrypted data cached: offset 778 length 102400
  * schannel: encrypted data buffer: offset 0 length 103424
  * schannel: decrypted data buffer: offset 778 length 102400
  * schannel: schannel_recv cleanup
  * schannel: decrypted data returned 778
  * schannel: decrypted data buffer: offset 0 length 102400
  &lt; HTTP/1.1 200 OK
  &lt; Content-Type: application/json; charset=UTF-8
  &lt; Vary: X-Origin
  &lt; Vary: Referer
  &lt; Date: Sat, 21 Jul 2018 00:11:31 GMT
  &lt; Server: ESF
  &lt; Cache-Control: private
  &lt; X-XSS-Protection: 1; mode=block
  &lt; X-Frame-Options: SAMEORIGIN
  &lt; X-Content-Type-Options: nosniff
  &lt; Alt-Svc: quic=":443"; ma=2592000; v="44,43,39,35"
  &lt; Accept-Ranges: none
  &lt; Vary: Origin,Accept-Encoding
  &lt; Transfer-Encoding: chunked
  &lt;
  {
    "instances": [
      ...
    ]
  }
  * Connection #0 to host bigtableadmin.googleapis.com left intact
  </code></pre>
  
  <p>Via jwt from node.js:</p>
  
  <pre><code>curl --header "Authorization: Bearer {jwt-from-node}" https://bigtableadmin.googleapis.com/v2/projects/{project-name}/instances -v
  &gt;
  * schannel: client wants to read 102400 bytes
  * schannel: encdata_buffer resized 103424
  * schannel: encrypted data buffer: offset 0 length 103424
  * schannel: encrypted data got 836
  * schannel: encrypted data buffer: offset 836 length 103424
  * schannel: decrypted data length: 773
  * schannel: decrypted data added: 773
  * schannel: decrypted data cached: offset 773 length 102400
  * schannel: encrypted data length: 34
  * schannel: encrypted data cached: offset 34 length 103424
  * schannel: decrypted data length: 5
  * schannel: decrypted data added: 5
  * schannel: decrypted data cached: offset 778 length 102400
  * schannel: encrypted data buffer: offset 0 length 103424
  * schannel: decrypted data buffer: offset 778 length 102400
  * schannel: schannel_recv cleanup
  * schannel: decrypted data returned 778
  * schannel: decrypted data buffer: offset 0 length 102400
  &lt; HTTP/1.1 401 Unauthorized
  &lt; WWW-Authenticate: Bearer realm="https://accounts.google.com/"
  &lt; Vary: X-Origin
  &lt; Vary: Referer
  &lt; Content-Type: application/json; charset=UTF-8
  &lt; Date: Sat, 21 Jul 2018 00:08:58 GMT
  &lt; Server: ESF
  &lt; Cache-Control: private
  &lt; X-XSS-Protection: 1; mode=block
  &lt; X-Frame-Options: SAMEORIGIN
  &lt; X-Content-Type-Options: nosniff
  &lt; Alt-Svc: quic=":443"; ma=2592000; v="44,43,39,35"
  &lt; Accept-Ranges: none
  &lt; Vary: Origin,Accept-Encoding
  &lt; Transfer-Encoding: chunked
  &lt;
  {
    "error": {
      "code": 401,
      "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See     https://developers.google.com/identity/sign-in/web/devconsole-project.",
      "status": "UNAUTHENTICATED"
    }
  }
  * Connection #0 to host bigtableadmin.googleapis.com left intact
  </code></pre>
  
  <p>How can i create JWT for Google service account using Node.js?</p>