通过Angular4连接到Google服务帐户时“无效授权类型”

时间:2017-08-25 01:13:49

标签: angular google-api google-cloud-datastore google-oauth

我一直在解决这个问题,并向任何指导开放。我有一个Angular 4应用程序,我使用Oauth创建对Google Cloud Datastore服务帐户的访问权限。我正在使用JWT并对其进行编码以传递给Google。以下是签名和HTTP请求的功能。

我不确定编码是否不正确,或者我是否尝试错误地访问API。打开我可能出错的地方的任何建议,或者更好的方法,这不会涉及到节点的背负。

获取令牌的功能:

getGoogleToken(){

let key = this.createGoogleSig();
let params = {
  grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
  assertion: key
};

 let myheaders = new Headers;

 myheaders.append('Content-Type', 'application/x-www-form-urlencoded')

console.log(params);

this.http.post('https://www.googleapis.com/oauth2/v4/token', params, { headers : myheaders}).subscribe(
  data => this.thing = data.toString(),
  err => console.log(err),
  () => console.log('Request Complete')
);

}

创建签名的代码

createGoogleSig(){

let now = (Date.now() / 1000).toFixed(0);
let exp = +now + 1800;

let key = {
  "type": "service_account",
  "project_id": "jenenginecms",
  "private_key_id": "---",
  "private_key": "-----BEGIN PRIVATE KEY-----cut for brevity---END PRIVATE KEY-----\n",
  "client_email": "pepperbirdcms@jenenginecms.iam.gserviceaccount.com",
  "client_id": "---",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/pepperbirdcms%40jenenginecms.iam.gserviceaccount.com"
}




let claimObj = {
  "iss": key.client_email,
  "scope": "https://www.googleapis.com/auth/datastore",
  "aud": "https://www.googleapis.com/oauth2/v4/token",
  "exp": exp,
  "iat": +now
}
console.log(claimObj);

let header = Base64.encodeURI('{"alg":"RS256","typ":"JWT"}');

let claimSet = Base64.encodeURI(JSON.stringify(claimObj));

let sig = new KJUR.crypto.Signature({ "alg": "SHA256withRSA" });

let privateKey = key.private_key;



let ret = encryptSignature();

let jwt = header + "." + claimSet + "." + ret;

console.log(jwt)
return jwt;

function encryptSignature() {
  sig.init(privateKey);
  sig.updateString(header + "." + claimSet);
  let cleaned_hex = sig.sign()

  let input = new Array();
  for (let i = 0; i < cleaned_hex.length / 2; i++) {
    let h = cleaned_hex.substr(i * 2, 2);
    input[i] = parseInt(h, 16);
  }

  let base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

  let ret = '';
  let i = 0;
  let j = 0;
  let char_array_3 = new Array(3);
  let char_array_4 = new Array(4);
  let in_len = input.length;
  let pos = 0;

  while (in_len--) {
    char_array_3[i++] = input[pos++];
    if (i == 3) {
      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] = char_array_3[2] & 0x3f;

      for (i = 0; (i < 4); i++)
        ret += base64_chars.charAt(char_array_4[i]);
      i = 0;
    }
  }

  if (i) {
    for (j = i; j < 3; j++)
      char_array_3[j] = 0;

    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
    char_array_4[3] = char_array_3[2] & 0x3f;

    for (j = 0; (j < i + 1); j++)
      ret += base64_chars.charAt(char_array_4[j]);

    while ((i++ < 3))
      ret += '=';

  }
  return ret;
}

}

1 个答案:

答案 0 :(得分:1)

实际上完整的错误非常有用:)

以此请求为例:

POST https://www.googleapis.com/oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer

当我执行此操作时,我

{
 "error": "invalid_request",
 "error_description": "Missing required parameter: assertion"
}

这是一个错误,但是“完全没问题,因为它是一个不同的错误。它证明Google认可此授权类型。现在看一下你的错误信息:

"error_description": "Invalid grant_type: "

描述字符串以冒号和空格结尾。这表明服务器未收到请求正文或无法解释它。为了证明这一点,我发送了另一个请求,这次是grant_type=thisdoesntexist,我得到了这个:

{
 "error": "unsupported_grant_type",
 "error_description": "Invalid grant_type: thisdoesntexist"
}

这意味着您的POST请求存在缺陷。我可以看到两个可能的问题:

  1. 标头设置不正确。像您一样使用Content-type: application/x-www-form-urlencoded是正确的想法,但是标题可能没有正确附加到您的请求中?

  2. 请求正文设置不正确。

  3. 我建议您仔细检查一下您是否正确实施了this.http.post来电,特别是我不知道应该做什么的data => this.thing = data.toString(),行。

    如果通过这样做您没有发现任何错误,您可以尝试监控您的请求。为此,您可以使用Fiddler之类的工具,也可以在本地Web服务器上快速设置脚本,只需回显标题和消息正文/ POST参数,并在应用内调用它,替换{{1} }。