Как авторизовать приложение (веб или установленное) без вмешательства пользователя?

Допустим, у меня есть веб-приложение, которому нужен доступ к файлам диска в фоновом режиме. Ему будут принадлежать файлы, к которым он обращается, или он будет запущен в учетной записи Google, с которой владелец поделился документами.

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

NB. Это НЕ использование Сервисной учетной записи. Приложение будет работать под обычной учетной записью Google. Я не говорю, что это хорошая идея, в некоторых ситуациях учетная запись является правильным подходом. Однако техника использования Oauth Playground для симуляции приложения может сэкономить массу лишних усилий и применяется к любым API, для которых совместное использование с учетной записью службы не поддерживается.

1 ответ

Решение

Это можно сделать с помощью Oauth2 Playground по адресу https://developers.google.com/oauthplayground

Шаги:-

  1. Создайте учетную запись Google (например, my.drive.app@gmail.com)
  2. Используйте консоль API для регистрации mydriveapp ( https://console.developers.google.com/apis/credentials/oauthclient?project=mydriveapp или просто https://console.developers.google.com/apis/).
  3. Создать новый набор учетных данных (NB OAuth Client ID не Service Account Key а затем выберите "Веб-приложение" из выбора)
  4. Добавьте https://developers.google.com/oauthplayground в качестве действительного URI перенаправления.
  5. Запишите идентификатор клиента (веб-приложение) и Client Secret
  6. Войдите как my.drive.app@gmail.com
  7. Перейти на площадку Oauth2
  8. В настройках (значок шестеренки) установите
    • Oauth flow: сервер
    • Тип доступа: автономный
    • Используйте свои собственные учетные данные OAuth: TICK
    • Идентификатор клиента и секрет клиента: с шага 5
  9. Нажмите Шаг 1 и выберите Drive API https://www.googleapis.com/auth/drive (сказав, что этот метод также работает для любого из перечисленных API Google)
  10. Нажмите Авторизовать API. Вам будет предложено выбрать свой аккаунт Google и подтвердить доступ
  11. Нажмите Шаг 2 и "Код авторизации Exchange для токенов"
  12. Скопируйте возвращенный токен обновления и вставьте его в свое приложение, исходный код или в какое-либо хранилище, откуда ваше приложение сможет его получить.

Ваше приложение теперь может запускаться без присмотра и использовать токен обновления, как описано https://developers.google.com/accounts/docs/OAuth2WebServer чтобы получить токен доступа.

NB. Имейте в виду, что срок действия маркера обновления может истечь, что означает, что вам нужно повторить шаги 5 и далее, чтобы получить новый токен обновления. Симптомом этого будет возвращение недействительного гранта при попытке использовать токен обновления.

NB2. Этот метод работает хорошо, если вам нужно веб-приложение, которое имеет доступ к вашей (и только к вашей) учетной записи Drive, не беспокоясь о том, чтобы написать код авторизации, который будет запускаться только один раз. Просто пропустите шаг 1 и замените "my.drive.app" своим собственным адресом электронной почты на шаге 5. Убедитесь, что вы знаете о последствиях для безопасности, если маркер обновления будет украден.

См. Ниже комментарий Вуди, где он ссылается на это видео Google https://www.youtube.com/watch?v=hfWe1gPCnzc

,,,

Вот небольшая процедура JavaScript, которая показывает, как использовать токен обновления из OAuth Playground, чтобы получить список некоторых файлов Drive. Вы можете просто скопировать и вставить его в консоль разработчика Chrome или запустить его с помощью узла. Конечно, предоставьте свои собственные учетные данные (ниже приведены все поддельные).

function get_access_token_using_saved_refresh_token() {
    // from the oauth playground
    const refresh_token = "1/0PvMAoF9GaJFqbNsLZQg-f9NXEljQclmRP4Gwfdo_0";
    // from the API console
    const client_id = "559798723558-amtjh114mvtpiqis80lkl3kdo4gfm5k.apps.googleusercontent.com";
    // from the API console
    const client_secret = "WnGC6KJ91H40mg6H9r1eF9L";
    // from https://developers.google.com/identity/protocols/OAuth2WebServer#offline
    const refresh_url = "https://www.googleapis.com/oauth2/v4/token";

    const post_body = `grant_type=refresh_token&client_id=${encodeURIComponent(client_id)}&client_secret=${encodeURIComponent(client_secret)}&refresh_token=${encodeURIComponent(refresh_token)}`;

    let refresh_request = {
        body: post_body,
        method: "POST",
        headers: new Headers({
            'Content-Type': 'application/x-www-form-urlencoded'
        })
    }

    // post to the refresh endpoint, parse the json response and use the access token to call files.list
    fetch(refresh_url, refresh_request).then( response => {
            return(response.json());
        }).then( response_json =>  {
            console.log(response_json);
            files_list(response_json.access_token);
    });
}

// a quick and dirty function to list some Drive files using the newly acquired access token
function files_list (access_token) {
    const drive_url = "https://www.googleapis.com/drive/v3/files";
    let drive_request = {
        method: "GET",
        headers: new Headers({
            Authorization: "Bearer "+access_token
        })
    }
    fetch(drive_url, drive_request).then( response => {
        return(response.json());
    }).then( list =>  {
        console.log("Found a file called "+list.files[0].name);
    });
}

get_access_token_using_saved_refresh_token();

Позвольте мне добавить альтернативный маршрут к отличному ответу pinoyyid (который не работал для меня - появление ошибок перенаправления).

Вместо использования OAuthPlayground вы также можете напрямую использовать HTTP REST API. Таким образом, разница с ответом pinoyyid состоит в том, что мы будем делать вещи локально. Выполните шаги 1-3 из ответа Пиноиды. Я процитирую их:

  1. Создайте учетную запись Google (например, my.drive.app@gmail.com). Или пропустите этот шаг, если вы используете существующую учетную запись.
  2. Используйте консоль API для регистрации mydriveapp ( https://console.developers.google.com/apis/credentials/oauthclient?project=mydriveapp или просто https://console.developers.google.com/apis/).
  3. Создайте новый набор учетных данных (NB OAuth-идентификатор клиента, а не ключ учетной записи службы, а затем выберите "Веб-приложение" из списка)

Теперь вместо игровой площадки добавьте к своим учетным данным следующее:

Авторизованные источники JavaScript: http://localhost/ (я не знаю, требуется ли это, но просто сделаю это.)
URI авторизованного перенаправления: http://localhost:8080/

Снимок экрана (на немецком языке):

Обязательно сохраните свои изменения с помощью синей кнопки ниже!

Теперь вы, вероятно, захотите использовать графический интерфейс для создания ваших HTTP-запросов. Я использовал бессонницу, но вы можете пойти с почтальоном или простой CURL. Я рекомендую Бессонницу, поскольку она позволяет легко проходить через экраны согласия.

Создайте новый запрос GET со следующими параметрами:

URL: https://accounts.google.com/o/oauth2/v2/auth
Query Param: redirect_uri=http://localhost:8080
Query Param: prompt=consent
Query Param: response_type=code
Query Param: client_id=<your client id from OAuth credentials>
Query Param: scope=<your chosen scopes, e.g. https://www.googleapis.com/auth/drive.file>
Query Param: access_type=offline

Если выбранный вами инструмент не обрабатывает кодировку URL автоматически, убедитесь, что вы все сделали правильно.

Перед тем как отправить запрос, настройте веб-сервер для прослушивания. http://localhost:8080, Если у вас установлен узел и npm, запустите npm i express затем создайте index.js:

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('ok');
  console.log(req)
});

app.listen(8080, function () {
  console.log('Listening on port 8080!');
});

И запустить сервер через node index.js, Я рекомендую либо не регистрировать весь req объект или бежать node index.js | less для полного выхода будет огромный.
Есть и очень простые решения для других языков. Например, использовать встроенный в PHP веб-сервер на 8080 php -S localhost:8080,

Теперь запустите ваш запрос (в Бессоннице), и вам будет предложено ввести логин:

Войдите со своим адресом электронной почты и паролем и подтвердите экран согласия (должен содержать выбранные вами области).

Вернитесь к своему терминалу и проверьте вывод. Если вы зарегистрировали все, прокрутите вниз (например, pgdown в less), пока не увидите строку с code=4/...,

Скопируйте этот код; это ваш код авторизации, который вы хотите обменять на токен доступа и обновления. Не копируйте слишком много - если есть амперсанд & не копируйте это или что-нибудь после. & Разграничивает параметры запроса. Мы просто хотим code,

Теперь настройте HTTP-запрос POST, указывающий на https://www.googleapis.com/oauth2/v4/token как закодирован URL формы. В Бессоннице вы можете просто щелкнуть это - в других инструментах вам, возможно, придется установить заголовок самостоятельно Content-Type: application/x-www-form-urlencoded,

Добавьте следующие параметры:

code=<the authorization code from the last step>
client_id=<your client ID again>
client_secret=<your client secret from the OAuth credentials>
redirect_uri=http://localhost:8080
grant_type=authorization_code

Опять же, убедитесь, что кодировка верна.

Запустите ваш запрос и проверьте вывод с вашего сервера. В ответе вы должны увидеть объект JSON:

{
  "access_token": "xxxx",
  "expires_in": 3600,
  "refresh_token": "1/xxxx",
  "scope": "https://www.googleapis.com/auth/drive.file",
  "token_type": "Bearer"
}

Вы можете использовать access_token сразу, но это будет действовать только в течение одного часа. Обратите внимание на маркер обновления. Это тот, который вы всегда можете * обменять на новый токен доступа.

* Вам придется повторить процедуру, если пользователь меняет свой пароль, отменяет доступ, неактивен в течение 6 месяцев и т. Д.

С Днем Рождения!

Другие вопросы по тегам