【问题标题】:Google Analytics: Invalid JWT Signature (invalid_grant) when trying to make authorized API callGoogle Analytics:尝试进行授权 API 调用时,JWT 签名无效 (invalid_grant)
【发布时间】:2017-07-27 20:28:28
【问题描述】:

我尝试对 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 基于 客户电子邮件: 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 的正确方法,或者可能是创建它的另一个服务。

谢谢!

【问题讨论】:

  • 你找到解决办法了吗
  • 我没有找到如何以这种方式弄清楚。或者,我使用了 Google Analytics API 客户端。
  • 我使用了这个库npmjs.com/package/google-oauth-jwt,并且我成功获得了令牌。希望它可以帮助其他面临类似问题的人
  • 我收到此错误,client_email 错误

标签: rest google-analytics oauth-2.0 jwt


【解决方案1】:

我有同样的问题, 我只是从google cloud platform 创建一个新的私钥

  IAM & admin -> Service accounts 

Service accounts for project项目名称

已经创建了你的服务账号,点击actions-> Create Key

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

【讨论】:

    【解决方案2】:

    对于任何探索这个问题的人,我有一组 PHP 代码来获取带有 JSON 服务帐户文件的令牌。这个 PHP sn-p 会给你一个用于获取 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 以获取分析数据。

    希望这对某人有所帮助,因为这在任何地方都没有得到很好的解释,并且需要一些挖掘才能正确地弄清楚加密。

    【讨论】:

    • 非常有用。我使用的是 .pem 文件,而不是从服务帐户生成的 json 文件。这有助于我正确配置它。
    【解决方案3】:

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

    【讨论】:

    • 虽然密钥没有过期,但创建一个新的密钥解决了我的问题。
    猜你喜欢
    • 2018-10-04
    • 2020-09-01
    • 1970-01-01
    • 2018-06-14
    • 2016-08-22
    • 2016-09-23
    • 1970-01-01
    • 2021-05-29
    • 2017-10-12
    相关资源
    最近更新 更多