Mit der Veröffentlichung von Qt 5.8 wurde das Modul QtNetworkAuth als ausstehende Technologie hinzugefügt. Es konzentriert sich darauf, Entwicklern bei ihrem Authentifizierungswahn zu helfen. Derzeit werden OAuth1 und OAuth2 unterstützt. In Zukunft werden weitere Autorisierungsmethoden hinzugefügt.
Dieser Beitrag konzentriert sich auf die OAuth2-Unterstützung von Qt. Dies zeigt, wie Sie die Google-Autorisierung in der App verwenden. Ihre Anwendung kann ein typisches Anmeldefenster wie eine Webanwendung anzeigen (Hinweis: Browser oder WebView erforderlich).
Die IETF definiert OAuth 2.0 als:
Das OAuth 2.0-Autorisierungsframework ermöglicht Anwendungen von Drittanbietern eingeschränkten Zugriff auf HTTP-Dienste, entweder durch den Ressourceneigentümer, um die Interaktion zwischen dem Ressourceneigentümer und dem HTTP-Dienst zu organisieren, oder um Anwendungen von Drittanbietern zu ermöglichen, ihren eigenen Zugriff zu erhalten.
Die OAuth-Autorisierung ist auch eine Voraussetzung für die Verwendung der Google-API und für den Zugriff des Benutzers auf Informationen, die in Google-Diensten wie Gmail, Drive, Youtube, Maps und anderen gespeichert sind.
Registrierung Ihres neuen Projekts
Bevor Sie mit dem Schreiben von Code beginnen, müssen Sie ein neues Projekt beim Dienstanbieter registrieren. Dieser Schritt ist erforderlich, da Sie zur Identifizierung Ihrer Anwendung zur Eingabe von Client-Anmeldeinformationen aufgefordert werden. Die folgenden Schritte basieren auf der Google API Console, sind aber für andere Anbieter ähnlich.
Erstellen Sie ein neues Projekt
Um mit der Registrierung eines Projekts zu beginnen, greifen Sie auf die Google API Console zu und klicken Sie dann auf „Projekt erstellen“.
Der Dialog „Neues Projekt“ erscheint. Geben Sie den Namen Ihres Projekts ein und klicken Sie auf die Schaltfläche "Erstellen". Jetzt können Sie Ihr neues Projekt verwalten.
Ihre Anwendung wurde registriert, das Bedienfeld wurde aktualisiert und Sie können in diesem Fenster verschiedene Optionen einstellen.
Erstellung von Anmeldeinformationen
Sie können Anmeldeinformationen abrufen, um die Anwendung zu identifizieren. Gehen Sie zum Abschnitt "Anmeldeinformationen" und klicken Sie auf die Schaltfläche "Anmeldeinformationen erstellen". Sie müssen auswählen, welche Anmeldeinformationen Sie benötigen. Wählen Sie „OAuth-Client-ID“.
Im nächsten Fenster können Sie einen „Zustimmungsbildschirm“ mit Ihrer E-Mail-Adresse, dem Produktnamen, der Homepage, dem Produktlogo usw. einrichten. Füllen Sie ihn mit Ihren Daten aus und klicken Sie auf die Schaltfläche „Speichern“.
Gehen Sie zurück zum Bildschirm „Client-ID erstellen“ und wählen Sie „Anwendungstyp". Hier stehen verschiedene Optionen zur Verfügung, Sie müssen „Webanwendung" auswählen. Geben Sie den Namen ein.
Unter „Restrictions“ gibt es ein wichtiges Feld: „Authorized Redirect URIs“.
Wenn der Benutzer seine Daten von Ihrer Anwendung verarbeiten lässt, akzeptiert die Anwendung ein „Zugriffstoken“, das für Autorisierungsanforderungen verwendet wird. "Zugriffstoken" kann auf verschiedene Arten akzeptiert werden, aber der übliche Weg ist, dass Ihr Webserver die Anfrage mit "Zugriffstoken" akzeptiert. In einer Webanwendung reicht der Serverpfad zur Verarbeitung aus. In einer Desktop-Anwendung müssen Sie den Pfad mit einem lokalen Browser vortäuschen.
Fügen Sie den Zugriffs-URI in Ihrem Browser hinzu, einschließlich des Ports, wenn Sie einen anderen Port als 80 verwenden. Wenn die Anwendung gestartet wird, erhält der Haupt-HTTP-Server Informationen vom Browser.
In den meisten Fällen müssen Sie einen URI ähnlich dem folgenden verwenden: „http://localhost:8080/cb“.
Hinweis: Der „/cb“-Pfad ist in der aktuellen QOAuthHttpServerReplyHandler-Implementierung erforderlich.
Hinweis: Sie können verschiedene URIs einrichten. Dieses Beispiel geht von einem einzelnen URI aus.
Wir schließen den Vorgang ab, indem wir auf die Schaltfläche "Erstellen" klicken, und Sie sehen die neue Identität in der Liste der Berechtigungen mit den Schaltflächen "Bearbeiten", "Löschen" und "Herunterladen" auf der rechten Seite. Klicken Sie auf den Download-Button und ... Und schließlich erhalten Sie eine fertige JSON-Datei zum Parsen!
Im obigen Screenshot sehen Sie einige der neuen URIs sowie client_id und client_secret. Es ist nicht erforderlich, eine JSON-Datei zu verwenden, Sie können diese Informationen direkt in der Anwendung fest codieren.
Wrapper-Code für Google API schreiben
Ein Teil der Klassendefinition wurde hier weggelassen, um den relevanten Code zu zeigen.
Erstellen Sie ein QOAuth2AuthorizationCodeFlow -Objekt in Ihrem Code:
auto google = new QOAuth2AuthorizationCodeFlow;
Festlegen der Scope -Berechtigungen, die für Ihre Anwendung erforderlich sind. Dieser Bereich definiert die Berechtigungen der Anwendung. Es kann eine einzelne Zeichenfolge oder eine Liste von Zeichenfolgen sein, die durch ein vom Dienstanbieter definiertes Zeichen getrennt sind. (Google verwendet Leerzeichen als Trennzeichen).
HINWEIS: Die Bereiche variieren je nach Anbieter. Eine Liste der von der Google-API unterstützten Bereiche finden Sie hier .
Lassen Sie uns den Bereich verwenden, von dem aus wir auf die E-Mail des Benutzers zugreifen:
google->setScope("email");
Verbinden Sie das Signal authorizeWithBrowser mit der Funktion QDesktopServices::openUrl , um einen externen Browser zu öffnen und die Autorisierung abzuschließen.
connect(google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);
Analysieren Sie das heruntergeladene JSON, um die Einstellungen und erforderlichen Informationen abzurufen. document ist ein Objekt der Klasse QJsonDocument aus der heruntergeladenen Datei.
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
Richten Sie nach dem Analysieren der Datei das Objekt google. ein
google->setAuthorizationUrl(authUri); google->setClientIdentifier(clientId); google->setAccessTokenUrl(tokenUri); google->setClientIdentifierSharedKey(clientSecret);
Erstellen Sie einen QOAuthHttpServerReplyHandler und weisen Sie ihn als Antworthandler des QOAuth2AuthorizationCodeFlow-Objekts zu. Ein Response-Handler ist ein Objekt, das Antworten vom Server verarbeitet und als Ergebnis des Autorisierungsprozesses Token empfängt.
auto replyHandler = new QOAuthHttpServerReplyHandler(port, this); google->setReplyHandler(replyHandler);
Die Funktion grant startet den Autorisierungsprozess.
google->grant();
Wenn alles in Ordnung ist, sollten Sie ein QOAuth2AuthorizationCodeFlow::granted -Signal erhalten und mit dem Senden von Autorisierungsanforderungen beginnen.
Sie können versuchen, eine Anfrage über https://www.googleapis.com/plus/v1/people/me zu senden
auto reply = google->get(QUrl("https://www.googleapis.com/plus/v1/people/me"));
Dadurch erhalten Sie QNetworkReply und wenn das Signal QNetworkReply::finished wird aufgerufen, damit Sie die Daten lesen können.
Источник 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 адреса, указанного при авторизации данным методом. Результат выводик как на скриншоте, но хочется увидеть конкретный адрес. Буду благодарен за любую помощь