如何获取Google服务帐户访问令牌javascript

Rot*_*ock 17 javascript google-analytics-api

我正在尝试设置我网站的分析仪表板,以便我查看网站使用情况.我不希望他们必须拥有一个谷歌帐户或单独添加它们才能看到结果.

我已经设置了服务帐户和OAuth2访问权限.我找到的所有教程都显示如下代码:

gapi.analytics.auth.authorize({
  clientid: 'Service account client ID',
  serverAuth: {
      access_token: 'XXXXXXXXXXXXXXXXX'
}
Run Code Online (Sandbox Code Playgroud)

所有的文档都谈到"......一旦你收到你的访问令牌......"但他们中没有人真正说出如何获得!我看到证书指纹,公钥指纹.我还看到了如何生成JSON和P12键.我没有看到如何生成访问令牌.

有人可以解释如何做到这一点?

我找到了这个.它解释说我需要密钥文件,这是一个坏主意,但没有说明如何实际做到这一点.

我也找到了这个.但我对Node.js一无所知,我希望这只是一条可能的路线?

Rot*_*ock 24

终于搞定了!使用kjur的jsjws纯JWT的JavaScript实现.我使用此演示作为生成JWT以请求令牌的基础.这是步骤

在Google Developers控制台中,我创建了一个服务帐户.以下是有关说明

在Google API控制台中,我将服务帐户添加到凭据中.然后我生成了一个新的JSON密钥.这给了我纯文本格式的私钥.

然后我按照谷歌的这些说明,使用HTTP/REST进行授权的API调用.

这是必需的标题信息.

var pHeader = {"alg":"RS256","typ":"JWT"}
var sHeader = JSON.stringify(pHeader);
Run Code Online (Sandbox Code Playgroud)

索赔集就是这样的.(这是使用由上述KJUR JWT库提供的语法.)

var pClaim = {};
pClaim.aud = "https://www.googleapis.com/oauth2/v3/token";
pClaim.scope = "https://www.googleapis.com/auth/analytics.readonly";
pClaim.iss = "<serviceAccountEmail@developer.gserviceaccount.com";
pClaim.exp = KJUR.jws.IntDate.get("now + 1hour");
pClaim.iat = KJUR.jws.IntDate.get("now");

var sClaim = JSON.stringify(pClaim);
Run Code Online (Sandbox Code Playgroud)

有争议的一点是将我的私钥放入客户端代码中.对于这种用法并没有那么糟糕(我不这么认为.)首先,该网站是我们公司防火墙的后面,所以谁会"破解"它?其次,即使有人确实得到了它,服务帐户的唯一授权就是查看我们的分析数据 - 我的仪表板的目的是访问该页面的任何人都可以查看我们的分析数据.不打算在这里发布私钥,但基本上就是这样.

var key = "-----BEGIN PRIVATE KEY-----\nMIIC....\n-----END PRIVATE KEY-----\n";`enter code here`
Run Code Online (Sandbox Code Playgroud)

然后生成一个签名的JWT

 var sJWS = KJUR.jws.JWS.sign(null, sHeader, sClaim, key);
Run Code Online (Sandbox Code Playgroud)

之后我使用XMLHttpRequest来调用google API.我尝试将FormData与请求一起使用,但这不起作用.所以老(呃)学校

var XHR = new XMLHttpRequest();
var urlEncodedData = "";
var urlEncodedDataPairs = [];

urlEncodedDataPairs.push(encodeURIComponent("grant_type") + '=' + encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer"));
urlEncodedDataPairs.push(encodeURIComponent("assertion") + '=' + encodeURIComponent(sJWS));
urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');

// We define what will happen if the data are successfully sent
XHR.addEventListener('load', function(event) {
    var response = JSON.parse(XHR.responseText);
    token = response["access_token"]
});

// We define what will happen in case of error
XHR.addEventListener('error', function(event) {
    console.log('Oops! Something went wrong.');
});

XHR.open('POST', 'https://www.googleapis.com/oauth2/v3/token');
XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
XHR.send(urlEncodedData)
Run Code Online (Sandbox Code Playgroud)

之后,我有了访问令牌,我可以按照这些教程使用embed API,但授权如下:

gapi.analytics.auth.authorize({
    serverAuth: {
        access_token: token
    }
});
Run Code Online (Sandbox Code Playgroud)

不要忘记,您必须授予服务帐户查看内容的权限,就像任何其他用户一样.当然,如果服务帐户被授权执行除只读之外的任何操作,那将是一个非常糟糕的主意.

我可能会遇到关于计时和令牌过期的问题,但到目前为止还很好.

  • 你不知道我一直在寻找这个.我花了很多时间在网上搜索一个成熟的,一步一步的例子(谷歌的文档是s***!).非常感谢你做的这些. (3认同)

And*_*ues 6

现在,服务帐户身份验证有一种getAccessToken方法可以为我们做到这一点。

const {google} = require('googleapis');

const main = async function() {
    
    const auth = new google.auth.GoogleAuth({
        keyFile: __dirname  + '/service-account-key.json',
        scopes: [ 'https://www.googleapis.com/auth/cloud-platform']
    });

    const accessToken = await auth.getAccessToken()
    
    console.log(JSON.stringify(auth, null, 4))
    console.log(JSON.stringify(accessToken, null, 4));
}

main().then().catch(err => console.log(err));

Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用官方(和Alpha)Node.js的Google API生成令牌。如果您有服务帐户,这将很有帮助。

在服务器上:

npm install -S googleapis
Run Code Online (Sandbox Code Playgroud)

ES6:

import google from 'googleapis'
import googleServiceAccountKey from '/path/to/private/google-service-account-private-key.json' // see docs on how to generate a service account

const googleJWTClient = new google.auth.JWT(
  googleServiceAccountKey.client_email,
  null,
  googleServiceAccountKey.private_key,
  ['https://www.googleapis.com/auth/analytics.readonly'], // You may need to specify scopes other than analytics
  null,
)

googleJWTClient.authorize((error, access_token) => {
   if (error) {
      return console.error("Couldn't get access token", e)
   }
   // ... access_token ready to use to fetch data and return to client
   // even serve access_token back to client for use in `gapi.analytics.auth.authorize`
})
Run Code Online (Sandbox Code Playgroud)