Как получить доступ к токену доступа к службе Google javascript

Я пытаюсь настроить панель аналитики моего сайта для моего руководства, чтобы посмотреть использование сайта. Я не хочу, чтобы они имели учетную запись google или добавляли их для просмотра результатов.

Я установил учетную запись службы и доступ к OAuth2. Все обучающие программы, которые я нахожу, показывают код следующим образом:

gapi.analytics.auth.authorize({
  clientid: 'Service account client ID',
  serverAuth: {
      access_token: 'XXXXXXXXXXXXXXXXX'
}

И вся документация говорит о "... как только вы получите свой токен доступа..." Но никто из них не говорит, как это получить! Я вижу сертификаты отпечатков пальцев, отпечатки пальцев открытого ключа. Я также вижу, как создавать ключи JSON и P12. Я не вижу, как сгенерировать токен доступа.

Может кто-нибудь объяснить, как это сделать?

Я нашел этот. Он объясняет, что мне нужен файл ключей и что это плохая идея, но не говорит, как это сделать на самом деле.

Я также нашел этот. Но я ничего не знаю о Node.js, и я надеюсь, что это всего лишь один из возможных путей?

Ответы

Ответ 1

Наконец-то он работает! Использование kjur jsjws для реализации JavaScript с использованием JavaScript JWT. Я использовал эту демонстрацию в качестве основы для генерации JWT для запроса токена. Вот шаги

В консоли Google Developers я создал учетную запись службы. Вот инструкции для этого

В консоли Google API я добавил учетную запись службы к учетным данным. Затем я сгенерировал новый ключ JSON. Это дает мне мой закрытый ключ в текстовом формате.

Затем я выполнил эти инструкции из Google, сделав авторизованный вызов API, используя HTTP/REST.

Это требуемая информация заголовка.

var pHeader = {"alg":"RS256","typ":"JWT"}
var sHeader = JSON.stringify(pHeader);

И набор требований - вот что. (Это использует синтаксис, который предоставляется библиотекой KJUR JWT, описанной выше.)

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

var sClaim = JSON.stringify(pClaim);

Спорный бит помещает мой закрытый ключ в код на стороне клиента. Для этого использования это не так уж плохо (я не думаю.) Во-первых, сайт стоит за нашим корпоративным брандмауэром, так кто же собирается его "взломать"? Во-вторых, даже если кто-то это получил, авторизация только для учетной записи службы - это просмотр наших данных аналитики, что является целью моей информационной панели, так это то, что любой, кто посещает страницу, может просматривать наши аналитические данные. Не собираюсь публиковать секретный ключ здесь, но в основном так.

var key = "-----BEGIN PRIVATE KEY-----\nMIIC....\n-----END PRIVATE KEY-----\n";`enter code here`

Затем сгенерирован подписанный JWT с

 var sJWS = KJUR.jws.JWS.sign(null, sHeader, sClaim, key);

После этого я использовал XMLHttpRequest для вызова API Google. Я попытался использовать 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)

После этого у меня есть токен доступа, и я могу следить за этими учебниками по использованию встроенного API, но авторизуясь так:

gapi.analytics.auth.authorize({
    serverAuth: {
        access_token: token
    }
});

Не забывайте, что вы должны предоставить разрешение учетной записи службы просмотра содержимого, как и любой другой пользователь. И, конечно, было бы очень плохо, если бы учетная запись службы разрешала делать что-либо, кроме чтения.

Вероятно, есть и проблемы с истечением срока действия и токена, с которыми я столкнулся, но пока что так хорошо.

Ответ 2

У вас есть (ниже) без одинарных кавычек

gapi.analytics.auth.authorize({
    serverAuth: {
        access_token: token
    }
});

но для его работы, согласно их документации, вам нужно разместить одинарные кавычки вокруг serverAuth и access_token.

gapi.analytics.auth.authorize({
    'serverAuth': {
        'access_token': token
    }
});

Ответ 3

Вы можете использовать официальный (и альфа) API Google для Node.js для создания токена. Это полезно, если у вас есть учетная запись службы.

На сервере:

npm install -S googleapis

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`
})