Google Analytics: Invalid JWT Signature (invalid_grant) when trying to make authorized API call

时间:2017-03-07 15:01:23

标签: rest google-analytics oauth-2.0 jwt

I trying to make authorized API call (HTTP/REST) to service account in Google Analytics. using this doc: https://developers.google.com/identity/protocols/OAuth2ServiceAccount

我只是使用HTTP / REST请求进行测试。

所以我有服务帐户的私钥文件:

{
  "type": "service_account",
  "project_id": "test-x",
  "private_key_id": "some_private_key_id",
  "private_key": "-----BEGIN PRIVATE KEY----- some_private_key -----END PRIVATE KEY-----",
  "client_email": "test-01@test-x.iam.gserviceaccount.com",
  "client_id": "some_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/test-01%40test-x.iam.gserviceaccount.com"
}

我基于创建JWT client_email: test-01@test-x.iam.gserviceaccount.com

部首:

{"alg":"RS256","typ":"JWT"}

索赔集:

{
  "iss": "test-01@test-x.iam.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/analytics.readonly",
  "aud": "https://www.googleapis.com/oauth2/v4/token",
  "exp": 1488820112,
  "iat": 1488816522
}

iat - 我只是设置了当前的

exp - 当前+ 1小时,

我使用此服务创建签名:https://jwt.io/#debugger

它生成我尝试用于访问令牌请求的编码值

当我尝试使用“编码”字段中的生成结果时:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=JWT_that_has_been_signed' https://www.googleapis.com/oauth2/v4/token

结果:

{
 "error": "invalid_grant",
 "error_description": "Invalid JWT Signature."
}

但我没有使用我的私钥。 根据计算签名的文档,我必须使用我的私钥。 我不完全理解如何正确使用密钥来正确计算签名。

jwt.io已生成PUBLIC和PRIVATE密钥......

可能我正在使用jwt.io错误..

请告诉我创建JWT的正确方法,或者可能是另一项创建JWT的服务。

谢谢!

3 个答案:

答案 0 :(得分:0)

我遇到了同样的问题, 我只是从(.*)

创建了一个新的私钥。
.*

google cloud platform项目名称

已经创建了您的服务帐户,单击 IAM & admin -> Service accounts

并更新项目上的私钥。希望对您有帮助。

答案 1 :(得分:0)

对于研究此问题的任何人,我都有一组PHP代码,用于获取带有JSON服务帐户文件的令牌。该PHP代码段将为您提供用于获取GA数据的令牌。

// assume $config is your json service account file converted to array
$config = "YOUR JSON FILE CONVERTED TO ARRAY";
$jwt_header = '{"alg":"RS256","typ":"JWT"}';
$jwt_header_cryph = urlencode(base64_encode($jwt_header));

$jwt_claim = '{
            "iss": "'.$config['client_email'].'",
            "scope":"https://www.googleapis.com/auth/analytics.readonly",
            "aud":"https://www.googleapis.com/oauth2/v4/token",
            "exp":'.(time()+3600).',
            "iat":'.time().'
        }';

$jwt_claim_cryph = urlencode(base64_encode($jwt_claim));

$data = $jwt_header_cryph.".".$jwt_claim_cryph;

$binary_signature = "";

$algo = "SHA256";
openssl_sign($data, $binary_signature, $config['private_key'], $algo);
$jws_signature_cryph = urlencode(base64_encode($binary_signature));

//concatenating the jwt request to complete it
$complete_request = $jwt_header_cryph.".".$jwt_claim_cryph.".".$jws_signature_cryph;

//build CURL request with post method
$url = 'https://www.googleapis.com/oauth2/v4/token';

//set POST variables
$fields = array(
    'grant_type' => urlencode('urn:ietf:params:oauth:grant-type:jwt-bearer'),
    'assertion' => $complete_request
);

$fields_string = "";
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, '&');

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true );

//execute post
$result = curl_exec($ch);

//close connection
curl_close($ch);

$token = json_decode($result, true);

变量$token将具有以下内容

[
  "access_token" => "your-access-token-string"
  "expires_in" => 3599
  "token_type" => "Bearer"
]

使用access_token字符串ping通GA以获取分析数据。

希望这对某人有帮助,因为在任何地方都无法很好地解释此问题,因此需要进行一些挖掘才能正确地找到加密。

答案 2 :(得分:0)

当密钥不再有效时,我收到此错误。我生成了一个新的服务帐号密钥并开始工作。