Evgenii Legotckoi
Evgenii Legotckoi26 січня 2017 р. 12:07

Підключення вашої Qt програми до сервісів Google за допомогою OAuth 2.0

З випуском 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

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

KL
  • 27 січня 2017 р. 14:39

При помощи данного класса можно получить доступ к google.com/webmaster?

Evgenii Legotckoi
  • 28 січня 2017 р. 06:33

Да. Можно. У Google есть соответствующее API. Поищите в гугле по запросу Google Search Console OAuth API

TheGringerEye
  • 20 квітня 2017 р. 19:48

Пытаюсь прикрутить к облаку яндекса и пока без успешно, кто-то пробовал с яндекс апи работать под этим классом?

Evgenii Legotckoi
  • 21 квітня 2017 р. 07:08

Лично я не пробовал работать с Яндекс API, не возникало такой нужды.

TheGringerEye
  • 24 квітня 2017 р. 03:36

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

Evgenii Legotckoi
  • 24 квітня 2017 р. 03:39

Возможно, стоит Wireshark`ом запросы посмотреть. В чём отличие идёт аякс запроса от запроса из библиотеки. Возможно, что не хватает какой-нибудь заголовочной информации.

TheGringerEye
  • 24 квітня 2017 р. 05:08

А с DropBox работали?

Evgenii Legotckoi
  • 24 квітня 2017 р. 09:38

Нет

TheGringerEye
  • 24 квітня 2017 р. 09:50

Пробовал играться с шарком, либо я криво смотрел, либо почему-то POST запросы на oauth.yandex.ru не летят, хотя должны постом лететь, я и исходники QOAuth2AuthorizationCodeFlow ковырял на предмет метода отправки, вроде бы везде POST, но в браузере GET открывается, ничего не понятно.

Evgenii Legotckoi
  • 24 квітня 2017 р. 10:44

У меня пока мыслей на этот счёт нет ((

D
  • 09 березня 2018 р. 02:56

Спасибо за статью.
Я правильно понял, что в консольных программах использовать данный способ авторизации не получится? (QDesktopServices требует QtGui.) Или QtNetworkAuth можно и по-другому использовать?

Evgenii Legotckoi
  • 09 березня 2018 р. 03:03

Вы можете написать консольную программу и использовать библиотеки QtGui. Я, например, использовал QImage и другие классы из QtGui в одной консольной программе. В этом нет никакой проблемы. Создаёте консольное приложение и подключаете в pro файле gui модуль.

D
  • 09 березня 2018 р. 03:10

Ну в общем-то, да. Тащить только дополнительные зависимости в код придётся.

D
  • 09 березня 2018 р. 03:14

Меня, в общем-то, авторизация в гугле заинтересовала, поскольку я пытаюсь в свой редактор контактов добавить импорт адресных книг с сетевых ресурсов. (Нет, сам он не консольный, а вполне себе оконный, просто на той же кодовой базе у меня есть и  простой конвертор с интерфейсом командной строки.) Загрузка с ресурсов вроде ownCloud/Nextcloud у меня уже работает через CardDAV, но в случае с гуглом всё сложнее именно из-за авторизации...

Evgenii Legotckoi
  • 09 березня 2018 р. 03:19

Зависимости... здесь вопрос в том, что "Вам шашечки или ехать?".

Если Вы хотите реализовать рабочий прототип приложения, то я бы на вашем месте и не думал о том, что будет на пару библиотек больше в коде, тем более, что это библиотеки из самого Qt, а не третьесторонние непонятно откуда. А когда заработает, то можно посмотреть исходники Qt, может тот метод состоит всего-то из пары, тройки строчек, которые можно скопипастить и почистить. Тогда и библиотека не понадобится в дальнейшем.
D
  • 17 березня 2018 р. 21:32

Интересный результат получается. В 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 на конце, хотя он у меня всюду вбит. Исходные данные одинаковы. Что-то поломали...

Evgenii Legotckoi
  • 18 березня 2018 р. 08:43

Мне кажется, что в Qt 5.10 много чего поломали... Вот на форуме некоторые обсуждения идут и создаётся впечатление, что много чего испортили даже в том же QML.

D
  • 22 березня 2018 р. 04:41

Кажется, начало что-то получаться. :)
Как я понял, пример проверочного вызова в конце статьи не совсем правильный (заглянул в английский оригинал - там то же самое). Токен сам к запросу не добавляется, его надо добавить вручную. Например, приведённый запрос для гуглоплюса у меня сработал в следующей редакции:

    QNetworkReply* reply = google->get(QUrl(
         QString("https://www.googleapis.com/plus/v1/people/me?access_token=%1")
             .arg(google->token())));
Ну и Google+ API при этом, конечно же, надо разрешить в настройках аккаунта (автор этот момент не раскрыл).

a
  • 24 березня 2022 р. 14:49

Добрый вечер. Интересует возможность получения email адреса, указанного при авторизации данным методом. Результат выводик как на скриншоте, но хочется увидеть конкретный адрес. Буду благодарен за любую помощь

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
Дмитрий

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:60бали,
  • Рейтинг балів-1
Дмитрий

C++ - Тест 003. Условия и циклы

  • Результат:92бали,
  • Рейтинг балів8
d
  • dsfs
  • 26 квітня 2024 р. 11:56

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
Останні коментарі
k
kmssr09 лютого 2024 р. 02:43
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко05 лютого 2024 р. 09:50
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 грудня 2023 р. 18:30
Boost - статичне зв&#39;язування в проекті CMake під Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 грудня 2023 р. 16:38
Boost - статичне зв&#39;язування в проекті CMake під Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 грудня 2023 р. 05:01
Qt/C++ - Урок 056. Підключення бібліотеки Boost в Qt для компіляторів MinGW і MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Тепер обговоріть на форумі
G
George1307 травня 2024 р. 07:27
добавить qlineseries в функции в функции: "GPlotter::addSeries(QString title, QVector &arr)" я вызываю метод setChart(...), я в конструктор передал адрес на QChartView элемент
BlinCT
BlinCT05 травня 2024 р. 12:46
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
PS
Peter Son04 травня 2024 р. 00:57
Best Indian Food Restaurant In Cincinnati OH Ready to embark on a gastronomic journey like no other? Join us at App india restaurant and discover why we're renowned as the Best Indian Food Restaurant In Cincinnati OH . Whether y…
Evgenii Legotckoi
Evgenii Legotckoi02 травня 2024 р. 21:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 квітня 2024 р. 11:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…

Слідкуйте за нами в соціальних мережах