З випуском Qt 5.8 був доданий модуль QtNetworkAuth як технологія на попередньому розгляді. Він сфокусований на допомозі розробникам зі своїм безумством в аутентифікації. На даний момент підтримуються OAuth1 та OAuth2 . У майбутньому буде включено ще кілька методів авторизації.
Цей пост спрямовано підтримку OAuth2 в Qt. Тут показано, як використовувати авторизацію Google у програмі. Ваша програма буде здатна показати типове вікно авторизації, як у веб-застосунку (Примітка: потрібен браузер або WebView).
IETF визначає OAuth 2.0, як:
OAuth 2.0 фреймворк авторизації дозволяє третім програмам отримати обмежений доступ до HTTP сервісів, або з боку власника ресурсу для організації взаємодії між власником ресурсу та HTTP сервісом, або дозволити програмам третьої сторони отримати власний доступ.
OAuth авторизація також є вимогою використання Google API та доступу користувача до інформації, яка зберігається в сервісах Google, таких як Gmail, Drive, Youtube, Maps та інших.
Реєстрація вашого нового проекту
Перед початком написання коду вам необхідно зареєструвати новий проект у сервіс-провайдері. Цей крок необхідний, оскільки ви будете вимагати облікові дані клієнта для ідентифікації вашої програми. Наступні кроки базуються на Google API Console, але вони схожі й на інших провайдерів.
Створення нового проекту
Щоб розпочати реєстрацію проекту, отримайте доступ до Google API Console , потім натисніть “Create Project”.
З'явиться діалог "New Project". Надрукуйте ім'я вашого проекту та натисніть кнопку "Create". Тепер ви готові керувати вашим новим проектом.
Ваша програма зареєстрована, панель керування оновлена і Ви можете встановити різні параметри цього вікна.
Створення облікових даних
Ви можете отримати облікові дані для ідентифікації програми. Перейдіть до розділу "Credentials" і натисніть кнопку "Create credentials". Ви повинні вибрати, які облікові дані вам потрібні. Виберіть “OAuth client ID”.
У наступному вікні, Ви можете налаштувати "екран згоди" з адресою електронної пошти, назва продукту, домашню сторінку, логотип продукту, ... Заповніть його вашими даними і натисніть кнопку "Save".
Поверніться назад до екрану “Create client ID” та виберіть "Application type". Тут доступні різні параметри, вам необхідно вибрати "Web application". Введіть його ім'я.
Під “Restrictions” є важливе поле: “Authorized redirect URIs”.
Якщо користувач вибирає дозволити вашому додатку обробляти його дані, то програма приймає “access token”, які використовуватимуться для запитів авторизації. "access token" може бути прийнятий декількома способами, але звичайним способом є прийом запиту своїм веб-сервером з "access token". У веб-застосунку, шляхи сервера достатньо для обробки. У робочому столі програмі необхідно підробити шлях, використовуючи локальний браузер.
Додайте URI Доступ у вашому браузері, включаючи порт, якщо Ви використовуєте порт, відмінний від 80-го. Коли програму буде запущено, основний HTTP сервер прийме інформацію від браузера.
У більшості випадків вам необхідно буде використовувати URI, схожий на: "http://localhost:8080/cb".
Примітка: Шлях "/cb" є обов'язковим у поточній реалізації QOAuthHttpServerReplyHandler.
Примітка: Ви можете налаштувати різні ідентифікатори URI. У цьому прикладі передбачається один URI.
Завершуємо процес, натиснувши кнопку "Create", і ви побачите нове посвідчення у списку повноважень з "Edit", "Delete" і "Download" кнопками справа. Натисніть кнопку завантаження та ... І, нарешті, ви отримаєте готовий файл у форматі JSON для синтаксичного аналізу!
На скріншоті вище ви можете побачити деякі нові ідентифікатори URI та client_id та client_secret. Там немає потреби використовувати файл у форматі JSON, ви можете жорстко задати цю інформацію безпосередньо у додатку.
Написання коду обгортки для Google API
Тут опущено частину визначення класу, щоб показати відповідний код.
Створіть у вашому коді об'єкт QOAuth2AuthorizationCodeFlow :
auto google = new QOAuth2AuthorizationCodeFlow;
Налаштування області дозволів, потрібних для вашої програми. Ця область визначає права доступу програми. Це може бути один рядок або список рядків, розділених символом, який визначається провайдером сервісу. (Google використовує пробіл як роздільник).
ПРИМІТКА: області залежить від постачальника. Щоб отримати список областей, що підтримуються Google API, натисніть тут .
Давайте використовувати область, з якою будемо отримувати доступ до електронної пошти користувача:
google->setScope("email");
Підключіть сигнал authorizeWithBrowser до функції QDesktopServices::openUrl для відкриття зовнішнього браузера та завершення авторизації.
connect(google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);
Розберіть завантажений JSON, щоб отримати налаштування та потрібну інформацію. document є об'єктом класу QJsonDocument із завантаженого файлу.
const auto object = document.object(); const auto settingsObject = object["web"].toObject(); const QUrl authUri(settingsObject["auth_uri"].toString()); const auto clientId = settingsObject["client_id"].toString(); const QUrl tokenUri(settingsObject["token_uri"].toString()); const auto clientSecret(settingsObject["client_secret"].toString()); const auto redirectUris = settingsObject["redirect_uris"].toArray(); const QUrl redirectUri(redirectUris[0].toString()); // Get the first URI const auto port = static_cast<quint16>(redirectUri.port()); // Get the port
Після парсингу файлу налаштуйте об'єкт google.
google->setAuthorizationUrl(authUri); google->setClientIdentifier(clientId); google->setAccessTokenUrl(tokenUri); google->setClientIdentifierSharedKey(clientSecret);
Створення та призначення QOAuthHttpServerReplyHandler як обробник відповіді об'єкта QOAuth2AuthorizationCodeFlow. Обробник відповіді є об'єктом, який обробляє відповіді від сервера та отримує token`и, як результат процесу авторизації.
auto replyHandler = new QOAuthHttpServerReplyHandler(port, this); google->setReplyHandler(replyHandler);
Функція grant розпочне процес авторизації.
google->grant();
Якщо все нормально, ви повинні отримати QOAuth2AuthorizationCodeFlow::granted signal і почати надсилати запити авторизації.
Ви можете спробувати надіслати запит, використовуючи https://www.googleapis.com/plus/v1/people/me
auto reply = google->get(QUrl("https://www.googleapis.com/plus/v1/people/me"));
Це дасть вам QNetworkReply і коли сигнал QNetworkReply::finished буде викликано, ви зможете прочитати дані.
Источник Qt Blog
При помощи данного класса можно получить доступ к google.com/webmaster?
Да. Можно. У Google есть соответствующее API. Поищите в гугле по запросу Google Search Console OAuth API
Пытаюсь прикрутить к облаку яндекса и пока без успешно, кто-то пробовал с яндекс апи работать под этим классом?
Лично я не пробовал работать с Яндекс API, не возникало такой нужды.
Жаль, а то проблемы возникли, по гайду с гуглом у меня всё чётко, а при работе с яндексом почему-то не работает, а в дебаг пишет мол 404, хотя я лично своими руками в браузере через аякс запрос постом нормально получаю токен, а класс чёт не хочет.
Возможно, стоит Wireshark`ом запросы посмотреть. В чём отличие идёт аякс запроса от запроса из библиотеки. Возможно, что не хватает какой-нибудь заголовочной информации.
А с DropBox работали?
Нет
Пробовал играться с шарком, либо я криво смотрел, либо почему-то POST запросы на oauth.yandex.ru не летят, хотя должны постом лететь, я и исходники QOAuth2AuthorizationCodeFlow ковырял на предмет метода отправки, вроде бы везде POST, но в браузере GET открывается, ничего не понятно.
У меня пока мыслей на этот счёт нет ((
Спасибо за статью.
Я правильно понял, что в консольных программах использовать данный способ авторизации не получится? (QDesktopServices требует QtGui.) Или QtNetworkAuth можно и по-другому использовать?
Вы можете написать консольную программу и использовать библиотеки QtGui. Я, например, использовал QImage и другие классы из QtGui в одной консольной программе. В этом нет никакой проблемы. Создаёте консольное приложение и подключаете в pro файле gui модуль.
Ну в общем-то, да. Тащить только дополнительные зависимости в код придётся.
Меня, в общем-то, авторизация в гугле заинтересовала, поскольку я пытаюсь в свой редактор контактов добавить импорт адресных книг с сетевых ресурсов. (Нет, сам он не консольный, а вполне себе оконный, просто на той же кодовой базе у меня есть и простой конвертор с интерфейсом командной строки.) Загрузка с ресурсов вроде ownCloud/Nextcloud у меня уже работает через CardDAV, но в случае с гуглом всё сложнее именно из-за авторизации...
Зависимости... здесь вопрос в том, что "Вам шашечки или ехать?".
Интересный результат получается. В Qt 5.8 получаю в браузере сформированное окно авторизации. А в новейшей Qt 5.10 - ошибку 400 с текстом "The redirect URI in the request, http://localhost:8080/, does not match the ones authorized for the OAuth client". Да, именно с таким URI, без /cb на конце, хотя он у меня всюду вбит. Исходные данные одинаковы. Что-то поломали...
Мне кажется, что в Qt 5.10 много чего поломали... Вот на форуме некоторые обсуждения идут и создаётся впечатление, что много чего испортили даже в том же QML.
Кажется, начало что-то получаться. :)
Ну и Google+ API при этом, конечно же, надо разрешить в настройках аккаунта (автор этот момент не раскрыл).Как я понял, пример проверочного вызова в конце статьи не совсем правильный (заглянул в английский оригинал - там то же самое). Токен сам к запросу не добавляется, его надо добавить вручную. Например, приведённый запрос для гуглоплюса у меня сработал в следующей редакции:
Добрый вечер. Интересует возможность получения email адреса, указанного при авторизации данным методом. Результат выводик как на скриншоте, но хочется увидеть конкретный адрес. Буду благодарен за любую помощь