![]() |
+7 (495) 229-0436 | ![]() |
shopadmin@itshop.ru | 119334, г. Москва, ул. Бардина, д. 4, корп. 3 | ![]() |
![]() |
![]() |
|
|
Применение C++ REST SDK в приложениях Windows Store17.01.2014 18:14
Сридхар ПодуриИсходный код можно скачать по ссылке. Продукты и технологии:
В предыдущей статье (msdn.microsoft.com/magazine/dn342869) я познакомил вас с C++ REST SDK и тем, как его можно использовать в Win32/MFC-приложениях. В этой статье мы обсудим, как C++ REST SDK можно интегрировать в приложения Windows Store. Одной из моих исходных целей в применении C++ REST SDK и класса аутентификации на основе OAuth было максимально полное использование стандартного C++ и лишь при необходимости взаимодействие со специфичными для платформы API. Кратко напомню суть предыдущей статьи.
Я поставил те же цели в своем приложении Windows Store для поддержки аутентификации и загрузки файла в Dropbox. Я стремился написать максимально больше портируемого кода на C++ и взаимодействовать с Windows Runtime (WinRT) только при необходимости. Проблемы с Win32-решениемОдним из крупных недостатков в предыдущем Win32-приложении была необходимость запуска внешнего приложения для выполнения процесса авторизации на основе OAuth. Это означало, что я должен был запускать Internet Explorer (можно было бы запускать и любой другой браузер), входить в Dropbox по своим удостоверениям, а затем выполнять необходимый рабочий процесс. Он проиллюстрирован на рис. 1 и 2.
Как видите, запуск внешнего приложения и предложение пользователям пройти рабочий процесс через внешнее приложение уводит фокус ввода из окна моего приложения. Как разработчик я также лишен стандартного механизма, через который мое приложение могло бы уведомляться о завершении этого рабочего процесса. При концентрации на асинхронном программировании и использовании C++ REST SDK, предназначенного для поддержки программирования на основе асинхронных задач, вынужденный запуск внешнего приложения со всей очевидностью является для меня неприятной ситуацией. Я исследовал подходы с применением именованных каналов (named pipes), проецируемых в память файлов (memory-mapped files) и т. д., но все эти подходы требуют создания другого приложения для хостинга экземпляра элемента управления "веб-браузер" и последующей записи значения, свидетельствующего об успехе, обратно через именованный канал, общую память или проецируемый в память файл. В итоге я остановился на использовании браузера для выполнения этой задачи, так как не хотел писать другую программу, которая обертывала бы элемент управления "веб-браузер". Одним из крупных недостатков в предыдущем Win32-приложении была необходимость запуска внешнего приложения для выполнения процесса авторизации на основе OAuth. Интеграция с Windows RuntimeНачав проектировать свое приложение под Windows Runtime, я рассмотрел несколько вариантов. Я вкратце расскажу о них здесь, а потом мы подробно обсудим выбранный мной подход.
WebAuthenticationBrokerВ мире подключенных приложений, чтобы получить согласие и одобрение пользователя, важно запрашивать его удостоверения через безопасный и доверяемый механизм. Никто не хочет быть разработчиком, чьи приложения допускают утечку удостоверений пользователя или оказываются уязвимыми к скрытым атакам с целью похищения информации о пользователе. Windows Runtime включает ряд API и необходимые технологии, позволяющие разработчику безопасно передавать удостоверения пользователя. WebAuthenticationBroker - одно из таких средств, которое дает возможность приложениям Windows Store использовать протоколы аутентификации и авторизации через Интернет, такие как OAuth и OpenID. Как же это работает в моем приложении-примере для Dropbox?
В мире подключенных приложений, чтобы получить согласие и одобрение пользователя, важно запрашивать его удостоверения через безопасный и доверяемый механизм. Рис. 3 иллюстрирует модальный диалог WebAuthenticationBroker в приложении-примере Dropbox после того, как веб-хост перешел на начальный URI. Поскольку Dropbox ожидает входа пользователей до появления страницы авторизации, веб-хост перенаправляет процесс навигации на страницу входа в Dropbox.
Как только пользователь вошел в Dropbox, веб-хост переходит к URI авторизации. Это отражено на рис. 4. Из рис. 3 и 4 понятно, что диалог размещается поверх UI моего приложения. UI также остается согласованным безотносительно приложения-источника, вызывающего метод WebAuthenticationBroker::AuthenticateAsync. Поскольку вся пользовательская среда сохраняет согласованность, пользователи могут предоставлять удостоверения, не беспокоясь о приложениях, обрабатывающих эту информацию, и о ее случайной утечке.
Одна важная вещь, о которой я не упомянул, - необходимость вызова функции WebAuthenticationBroker::AuthenticateAsync из UI-потока. Все веб-запросы в C++ REST SDK выдаются в фоновом потоке, а вывести UI из фонового потока нельзя. Поэтому я использую системный диспетчер и вызываю его функцию-член RunAsync для отображения модального UI (рис. 5). Рис. 5. Использование системного диспетчера для отображения модального UI
Как только пользователь вошел в Dropbox, веб-хост переходит к URI авторизации. По окончании процесса авторизации я снова запускаю диспетчер, чтобы сделать доступной кнопку Upload File в основном UI. Эта кнопка остается недоступной, пока пользователи не аутентифицировали и не авторизовали мое приложение для доступа к Dropbox. Создание цепочки асинхронных веб-запросовТеперь легко свести все воедино. Во всех функциях, не взаимодействующих с Windows Runtime, я повторно использовал код из моего настольного приложения. Крупных изменений в коде нет, кроме одного: в функции UploadFileToDropboxAsync вместо C++ iostream используется WinRT-объект StorageFile. При написании приложений Windows Store приходится учитывать некоторые ограничения, с которыми вы должны смириться. Одно из них - необходимость использования WinRT-объектов StorageFile вместо C++-потоков (streams) для чтения и записи данных в файлы. При разработке приложения Windows Store с применением C++ REST SDK все операции, связанные с файлами, ожидают передачи объекта StorageFile, а не C++-объекта потока данных. Внеся это небольшое изменение, я смог повторно использовать весь свой стандартный C++-код, поддерживающий код OAuth-авторизации и Dropbox, в приложении-примере для Windows Store. Вот как выглядит соответствующий псевдокод (индивидуальные функции мы обсудим после этого псевдокода): При щелчке кнопки SignIn Вызов функции oAuthLoginAsync Затем вызов WebAuthenticationBroker::AuthenticateAsync Затем делаем доступной кнопку Upload File в UI При щелчке кнопки Upload File Вызов функции Windows::Storage::Pickers::FileOpenPicker:: PickSingleFileAsync Затем вызов функции oAuthAcquireTokenAsync Затем вызов функции UploadFileToDropboxAsync В обработчике событий кнопки SignInBtnClicked, показанном на рис. 6, я сначала выполняю простую проверку параметров, чтобы удостовериться, что в параметрах ConsumerKey и ConsumerSecret не передаются пустые строки, отправляемые потом в Dropbox для аутентификации. Затем я получаю экземпляр объекта Dispatcher, сопоставленного с текущим потоком CoreWindow, и сохраняю его как переменную-член класса MainPage. Dispatcher отвечает за обработку оконных сообщений и диспетчеризацию событий для приложения. Далее я создаю экземпляр класса OnlineIdAuthenticator. Этот класс содержит вспомогательные функции, которые позволяют мне выводить модальное диалоговое окно приложения и выполнять защищенный рабочий процесс авторизации. Это избавляет от необходимости запуска экземпляра браузера и перевода фокуса ввода с приложения в браузер. Рис. 6. Функция SignInBtnClicked
Затем я вызываю функцию OAuthLoginAsync, которая выполняет операцию входа в Dropbox. Как только эта асинхронная функция возвращает управление, я использую функцию RunAsync объекта Dispatcher для маршалинга вызова обратно в UI-поток из фонового потока асинхронной задачи. Функция RunAsync принимает два параметра: значение приоритета и экземпляр DispatchedHandler. Я задаю приоритет как "Normal" и передаю функцию лямбды экземпляру DispatchedHandler. В теле лямбды я вызываю статическую функцию AuthenticateAsync класса WebAuthenticationBroker, которая потом отображает модальный диалог приложения и помогает выполнить защищенную аутентификацию. При написании приложений Windows Store приходится учитывать некоторые ограничения, с которыми вы должны смириться. По окончании рабочего процесса диалог удаляется, и функция возвращает либо код успешного завершения, либо обнаруженные ошибки. В моем случае я просто обрабатываю возвращаемый тип WebAuthenticationStatus::Success и снова использую объект диспетчера, чтобы сделать доступной кнопку UploadFile в UI. Поскольку все вызываемые мной функции являются асинхронными, мне нужно задействовать объект диспетчера для маршалинга вызовов в UI-поток, если я хочу обращаться к каким-либо UI-элементам. Обработчик событий UploadFileBtnClicked показан на рис. 7. В самом обработчике кода не так уж много. Я вызываю функцию FileOpenPicker::PickSingleFileAsync, которая позволяет выбрать один текстовый файл через интерфейс выбора (picker interface). Затем вызываю функцию OAuthAcquireTokenAsync (рис. 8) и при успешном завершении обращаюсь к функции UploadFileToDropBoxAsync (рис. 9). Рис. 7. Функция UploadFileBtnClicked
Рис. 8. Функция OAuthAcquireTokenAsync
Рис. 9. Функция UploadFileToDropBoxAsync
Функция OAuthAcquireTokenAsync получает маркер, сопоставленный с учетной записью Dropbox. Сначала я формирую необходимую строку доступа (access string) и заголовки HTTP-запроса и вызываю сервис Dropbox для проверки удостоверений. Этот HTTP-запрос имеет тип GET, а ответ возвращается как поток символов. Я разбираю этот поток для получения самого маркера и секрета, которые потом сохраняются в экземпляре класса AppCredentials. Успешно получив маркер и его секрет от Dropbox, я использую их для загрузки файла в Dropbox. Как и в случае любой конечной точки веб-доступа к Dropbox, сначала формируется строка параметров и HTTP-заголовки. Затем вызывается конечная точка сервиса Dropbox, сопоставленная с загрузкой файлов. Этот HTTP-запрос имеет тип PUT, поскольку я пытаюсь поместить контент в сервис. Перед этим мне также нужно сообщить Dropbox о размере контента. Это указывается установкой значения свойства content_length в методе HTTP_request::set_body равным размеру загружаемого файла. После успешного возврата PUT-метода с помощью объекта диспетчера я вывожу пользователю сообщение об успешном завершении операции. На очереди LinuxИнтеграция C++ REST SDK в приложения Windows 8 (как Windows Store, так и настольные) проста и прямолинейна. Добавьте преимущества написания кода, который может быть общим между двумя платформами, применение идиом программирования на современном C++ и тот факт, что данный код является портируемым между приложениями как Windows, так и других ОС, - и приз ваш. Вы можете больше не беспокоиться о специфичных для платформ тонкостях, относящихся к сетевым API, и вместо этого уделять больше времени продумыванию функциональности, которую должно поддерживать ваше приложение. В этом простом примере я задействовал C++ REST SDK для аутентификации пользователя в Dropbox и последующей загрузки файла в облако Dropbox. Подробнее о Dropbox REST API см. документацию по ссылке bit.ly/10OdTD0. В следующей статье я покажу, как выполнять те же задачи из Linux-клиента. Сридхар Подури (Sridhar Poduri) - менеджер программ в группе Windows в Microsoft. Страстный поклонник C++ и автор книги "Modern C++ and Windows Store Apps" (Sridhar Poduri, 2013), регулярно пишет о C++ и Windows Runtime в своем блоге sridharpoduri.com. Выражаю благодарность за рецензирование статьи экспертам Microsoft Никласу Густаффсону (Niklas Gustaffson), Сана Митани (Sana Mithani) и Огги Шобахичу (Oggy Sobajic). |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
О нас |
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.
На протяжении многих лет интернет-магазин предлагает товары и услуги, ориентированные на бизнес-пользователей и специалистов по информационным технологиям. Хорошие отзывы постоянных клиентов и высокий уровень специалистов позволяет получить наивысший результат при совместной работе. В нашем магазине вы можете приобрести лицензионное ПО выбрав необходимое из широкого спектра и ассортимента по самым доступным ценам. Наши менеджеры любезно помогут определиться с выбором ПО, которое необходимо именно вам. Также мы проводим учебные курсы. Мы приглашаем к сотрудничеству учебные центры, организаторов семинаров и бизнес-тренингов, преподавателей. Сфера сотрудничества - продвижение бизнес-тренингов и курсов обучения по информационным технологиям.
|
119334, г. Москва, ул. Бардина, д. 4, корп. 3 +7 (495) 229-0436 shopadmin@itshop.ru |
|
© ООО "Interface Ltd." Продаем программное обеспечение с 1990 года |