Как я могу получить токен OAuth2 учетной записи службы из Google Api с помощью Javascript?

Мне нужно использовать учетную запись службы проектов Google для доступа к API Google с помощью JavaScript. Для этого мне нужно OAuth2 для серверов API Google, чтобы получить токен аутентификации.

Я понимаю, что Google предоставляет библиотеку (GAPI) для использования на серверах узлов, но мне нужно решение, которое будет работать в других безопасных средах JavaScript.


person N-ate    schedule 10.11.2017    source источник


Ответы (1)


Эта задача состоит из двух основных частей.

  1. Настройка
  2. Кодирование

Сначала выполните шаги Конфигурация.

  • If you don't have a google account:
    1. Navigate to google.com
    2. Найдите и нажмите «Войти».
    3. Нажмите "Дополнительные параметры"
    4. Нажмите «Создать учетную запись».
    5. Следуйте инструкциям, чтобы создать учетную запись
  • Перейдите на панель управления api: console.developers.google.com/apis/dashboard.
  • Выберите или создайте проект, щелкнув текущий проект. Показываемый мной проект называется "Мой проект"  введите описание изображения здесь

  • Щелкните google enable apis and services и включите те API, с которыми вы планируете работать

  • перейдите в раздел учетных данных: console.developers.google.com/apis/credentials
  • Click google create credentials and select "Service account key"
  • Убедитесь, что «Тип ключа» - «Json», и нажмите «Создать». Ваш ключ / сертификат загрузится автоматически

Теперь о разделе Кодирование.

  • Сначала загрузите jsrsasign и добавьте ссылку на «jsrsasign-all-min.js». Если хотите, можете скачать с github просто "jsrsasign-all-min.js".
  • Во-вторых, обновите следующий скрипт своим сертификатом / ключом (загруженным ранее):

    function postJWT(jwt, callback) {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function () {
            if (this.readyState == 4) {
                if (this.status == 200 && callback) {
                    callback(this.responseText);
                    return;
                }
                if (console) console.log(this.responseText);
            }
        };
        var parameters = "grant_type=" + encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer") + "&assertion=" + encodeURIComponent(jwt);
        xhttp.open("POST", "https://www.googleapis.com/oauth2/v4/token", true);
        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhttp.send(parameters);
    }
    
    function getCert() {
        var cert = //your json key (downloaded earlier) goes here
            {
                "type": "service_account",
                "project_id": "proj..",
                "private_key_id": "e18..",
                "private_key": "-----BEGIN PRIVATE KEY-----\nMII..==\n-----END PRIVATE KEY-----\n",
                "client_email": "[email protected]",
                "client_id": "5761..",
                "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/..service-account%40...iam.gserviceaccount.com"
            };      
        return cert;
    }
    function getJWT() {
        var cert = getCert();
        var key = KEYUTIL.getKey(cert.private_key);
        var headers = { "alg": "RS256", "typ": "JWT" };
        var issued = Math.floor(new Date().getTime()/1000);
    
        var claims = {
            "iss": cert.client_email,
            "scope": "https://www.googleapis.com/auth/analytics.readonly",
            "aud": "https://www.googleapis.com/oauth2/v4/token",
            "exp": issued + 3600,
            "iat": issued
        };
    
        var jwt = KJUR.jws.JWS.sign(headers.alg, headers, JSON.stringify(claims), key);
        return jwt;
    }
    
  • Когда вы тестируете свой код, вы должны получить обратно объект json с токеном аутентификации. Вы можете протестировать свою реализацию так:

    postJWT(getJWT(text), function(){
        let token = JSON.parse(response).access_token;
        //Do your api calls here using the token. 
        //Reuse the token for up to 1 hour.
    });
    

Вот пример успешного json-объекта с токеном:

{
    "access_token": "ya29.c.ElkABZznrLNLK6ZAq2ybiH5lsRJpABE8p7MlZZJ0WCKcDNDv75lh-o1iRX__uMNUKSySiawm4YJGsbfqJH2JH61nRK6O2m0GJR7DgkEmo6ZlKtrvzke9C3xpwA",
    "token_type": "Bearer",
    "expires_in": 3600
}

Обратите внимание, что этот подход требует, чтобы ключ / сертификат были доступны из вашей среды javascript. Если эта среда является общедоступной, ваш API уязвим.

person N-ate    schedule 10.11.2017
comment
Привет, я хотел бы знать, как использовать это в сочетании с вызовом API Google Analytics - person Elvira; 29.11.2017
comment
@Elvira Я обновил код, чтобы отразить, где вы должны разместить свой вызов api. Если вам нужна помощь в настройке вызова API с использованием токена, задайте новый вопрос и отметьте меня тегом или свяжите его здесь, чтобы я мог помочь. Я постараюсь следить за этим. - person N-ate; 29.11.2017
comment
Мне удалось выполнить приведенные выше инструкции, и я могу войти в систему и получить токен для учетной записи службы. Однако, когда я пытаюсь получить данные календаря из gapi, я получаю пустой массив. Кто-нибудь здесь может помочь и дать совет? ссылка - person El Fred; 20.01.2019
comment
Сможете ли вы читать что-нибудь в календаре или еще что-нибудь? Можете написать в календарь или другой api? Возможно, у вас нет разрешения на доступ к календарю, но я не могу однозначно сказать, в чем ваша проблема. - person N-ate; 21.01.2019
comment
Не забудьте проголосовать за вопрос, а не только за ответ, если он вам помог, чтобы другим было легче найти эту ветку. Не стесняйтесь писать мне напрямую. Спасибо! - person N-ate; 21.01.2019
comment
Чтобы импортировать jsrsasign, я загрузил файл .js и добавил ниже три строки в функцию getJWT (): var import = document.createElement ('script'); import.src = 'jsrsasign-all-min.js'; document.head.appendChild (импортировано); - person jkr; 01.01.2021