Google Analytics(分析):尝试进行授权的API调用时,JWT签名无效(invalid_grant) [英] Google Analytics: Invalid JWT Signature (invalid_grant) when trying to make authorized API call

查看:340
本文介绍了Google Analytics(分析):尝试进行授权的API调用时,JWT签名无效(invalid_grant)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图对Google Analytics(分析)中的服务帐户进行授权的API调用(HTTP/REST). 使用此文档: 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的另一项服务.

谢谢!

解决方案

对于研究此问题的任何人,我都有一组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以获取分析数据.

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

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

I just use HTTP/REST request to test.

So I have service account's private key file:

{
  "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"
}

I create JWT based on client_email: test-01@test-x.iam.gserviceaccount.com

Header:

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

Claim set:

{
  "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 - I just set current

exp - current + 1 hour,

I use this service to create signature: https://jwt.io/#debugger

It generates encoded value which I try to use for access token request

When I try to use generated result from "Encoded" field:

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

result:

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

But I not use my private key. Accordingly to documentation for computing the signature I have to use my private key. I not completely understand how to use key in right way to compute the signature correctly.

jwt.io already generates PUBLIC and PRIVATE key...

Probably I'm using jwt.io incorrectly..

Please advise me the correct way of creating JWT or may be another service to create it.

Thanks!

解决方案

For anyone exploring this issue, I have a set of code in PHP to get the token with the JSON service account file. This PHP snippet will get you a token to use to get GA data.

// 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);

The variable $token will have the following content

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

Use the access_token string to ping GA for analytics data.

Hopefully this helps someone along as this is not well explained much anywhere and it took some digging to figure out the encryption properly.

这篇关于Google Analytics(分析):尝试进行授权的API调用时,JWT签名无效(invalid_grant)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆