2

I have enabled a Service Account from Google API Console to perform two-legged OAuth for making calls to Google Analytics API. I am using JavaScript and have followed the pure JavaScript implementation of JWT and JWS to generate a signed JWT and make the HTTP/REST call for a token as described in this guide. Once I make the POST with the encodedURL I get a 400 "error": "invalid_grant". "error_description": "Bad Request"

I read some posts to be sure to include the email and not client_id in request. I made sure that was the case and since then Google has updated their Documentation.

Any Ideas? I will post code also if necessary but I mostly followed Rothrock's post at this link.

I tried the signed JWT on http://jwt.io/ and it says it's invalid signature. The payload and header decode correctly. Is there a way to test the signature after encoding with private key provided by Google API console?

Here is my code:

  var pHeader = {"alg":"RS256", "typ":"JWT"};
  var sHeader = JSON.stringify(pHeader);
  var pClaim ={};
  pClaim.iss = "(ServiceAccount_Email_Address).apps.googleusercontent.com";
  pClaim.scope = "https://www.googleapis.com/auth/analytics.readonly";
  pClaim.aud = "htps://www.googleapis.com/oauth2/v3/token";
  pClaim.exp = KJUR.jws.IntDate.get("now + 1hour");
  pClaim.iat = KJUR.jws.IntDate.get("now");

  var sClaim = JSON.stringify(pClaim);

  var key = "-----BEGIN PRIVATE KEY----- Private Key from JSON file ----END PRIVATE KEY-----"; 

  var sJWS = KJUR.jws.JWS.sign('RS256', sHeader, sClaim, key);
  var urlEncodedData = '';
  var urlEncodedDataPairs = [];
  var token;
  urlEncodedDataPairs.push("grant_type" + '=' + "urn:ietf:params:oauth:grant-type:jwt-bearer");
  urlEncodedDataPairs.push("assertion" + '=' + sJWS);
  urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g,'+');

 $(function(){
    $.ajax({
              type: "POST",
              url: 'https://www.googleapis.com/oauth2/v3/token',
              data: urlEncodedData,
              dataType: 'JSON',
              contentType: 'application/x-www-form-urlencoded',
              success: function(result){
                console.log(JSON.stringify(result));
              }
    });
 });
Community
  • 1
  • 1
Ojen G.
  • 173
  • 1
  • 3
  • 9

1 Answers1

1

I found the answer to this sometime back, but want to post it here for clarification. Everything in the code above is correct. The SSH key provided had some \n chars in it which are valid. My key had a line between -----BEGIN PRIVATE KEY----- and the starting of the actual string of key.

Ojen G.
  • 173
  • 1
  • 3
  • 9