Авторизация OAuth для Xamarin-приложений

в 14:57, , рубрики: Binwell, Developer Day 2017, microsoft, oauth, xamarin, xamarin.forms, xamarincolumn, Блог компании Microsoft, кроссплатформенная разработка, мобильная разработка, мобильные приложения, разработка мобильных приложений, Разработка под android, разработка под iOS

Итак, сегодня мы продолжаем разбираться с различными механизмами авторизации пользователей в приложениях на Xamarin. После знакомства с SDK от Facebook и ВКонтакте (здесь и здесь), можем перейти к одному из самых популярных (на текущий момент) механизмов внешней авторизации пользователей — OAuth. Большинство популярных сервисов вроде Twitter, Microsoft Live, Github и так далее, предоставляют своим пользователям возможность входа в сторонние приложения с помощью одного привычного аккаунта. Научившись работать с OAuth вы легко сможете подключать все эти сервисы и забирать из них информацию о пользователе.

Авторизация OAuth для Xamarin-приложений - 1

Авторизация OAuth для Xamarin-приложений - 2

Предполагается, что вы уже знакомы с тем, как работает OAuth, а если нет — рекомендуем вот эту хорошую статью на Хабре. Если коротко, то при авторизации OAuth пользователь перенаправляется с одной веб-страницы на другую (обычно 2-3 шага) до тех пор, пока не перейдет на конечный URL. Этот финальный переход и будет отловлен в приложении (если писать логику самому) на уровне WebView, а нужные данные (token и срок его валидности) будут указаны прямо в URL.

Небольшой список популярных сервисов, которые предоставляют возможность авторизации пользователей по OAuth: Одноклассники, Mail.ru, Dropbox, Foursquare, GitHub, Instagram, LinkedIn, Microsoft, Slack, SoundCloud, Visual Studio Online, Trello.

Xamarin.Auth

Для того, чтобы работать с OAuth в Xamarin мы остановимся на простой и удобной библиотеке Xamarin.Auth, которая развивается уже не первый год и имеет все необходимые для нас механизмы:

  1. Отображение браузера со страницами авторизации
  2. Управление потоком редиректов и процессом авторизации
  3. Получение нужных данных
  4. Предоставление механизмов для дополнительных запросов к сервису, например для получения информации о пользователе

Также Xamarin.Auth поддерживает возможность хранения учетных данных пользователя в защищенном хранилище. В общем, зрелый и качественный компонент с необходимой функциональностью.

Рекомендуем устанавливать Xamarin.Auth из Nuget, так как версия в Xamarin Components уже давно устарела и не обновляется.

Авторизация OAuth для Xamarin-приложений - 3

Напомню, что мы уже ранее рассказывали про авторизацию с помощью SDK от Facebook и ВКонтакте. В нашем примере мы вынесли всю логику авторизации в платформенные проекты, оставив в PCL только интерфейсы. Для OAuth мы пойдем тем же путем, несмотря на поддержку PCL в самом Xamarin.Auth.

Помимо Xamarin.Auth можем также порекомендовать библиотеку Xamarin.Forms.OAuth от Bruno Bernardo. Даже если вы используете классический Xamarin, в исходных кодах этого проекта можно найти множество готовых конфигураций для различных сервисов.

Мы же в качестве примера работы OAuth подключим авторизацию с помощью Microsoft. Первым делом создадим приложение на сайте https://apps.dev.microsoft.com и получим там Client ID (ИД клиента или приложения).

Авторизация OAuth для Xamarin-приложений - 4

Подключаем авторизацию в PCL

На уровне PCL все как обычно — делаем простой интерфейс IOAuthService для платформенного сервиса, никаких новых зависимостей в проект не добавляем.

public interface IOAuthService
{
   Task<LoginResult> Login();
   void Logout();
}

Ну и, конечно же, будет необходимо добавить обращение к методам DependencyService.Get<IOAuthService>().Login() и DependencyService.Get<IOAuthService>().Logout() внутри нашей страницы авторизации.

Также нет проблем добавить поддержку нескольких OAuth-сервисов. Для этого можно добавить в методы Login() и Logout() аргумент providerName (тип string, int или enum) и в зависимости от его значения выбирать поставщика услуг.

Реализация платформенной части

Как уже отмечалось ранее, необходимо добавить библиотеки Xamarin.Auth из Nuget в каждый платформенный проект, в нашем случае — iOS и Android. Дальше пишем нашу реализацию IOAuthService для каждой платформы и регистрируем ее в качестве Dependency.

Теперь нам достаточно создать экземпляр класса OAuth2Authenticator с нужными параметрами:

         var auth = new OAuth2Authenticator
           (
               clientId: "ВАШ_CLIENT_ID",
               scope: "wl.basic, wl.emails, wl.photos",
               authorizeUrl: new Uri("https://login.live.com/oauth20_authorize.srf"),
               redirectUrl: new Uri("https://login.live.com/oauth20_desktop.srf"),
               clientSecret: null,
               accessTokenUrl: new Uri("https://login.live.com/oauth20_token.srf")
           )
           {
               AllowCancel = true
           };

Теперь повесим обработчик завершения авторизации:

auth.Completed += AuthOnCompleted;

Всё, можно показать модальное окно со встроенным веб-браузером для авторизации, получаемое через метод auth.GetUI(). На iOS это можно сделать примерно так:

UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(auth.GetUI(), true, null);

На Android при использовании Xamarin.Forms код может получится следующим:

Forms.Context.StartActivity(auth.GetUI(Forms.Context));

После успешной авторизации вызовется наш метод AuthOnCompleted(), и для iOS будет необходимо скрыть модальное окно с браузером (на Android само скроется):

UIApplication.SharedApplication.KeyWindow.RootViewController.DismissViewController(true, null);

Теперь можно получать нужные данные (access_token и время его жизни в секундах — expires_in)

var token = authCompletedArgs.Account.Properties["access_token"];                
var expireIn = Convert.ToInt32(authCompletedArgs.Account.Properties["expires_in"]);
var expireAt = DateTimeOffset.Now.AddSeconds(expireIn);

И нам остался последний шаг — получить расширенную информацию из профиля пользователя, включая email и ссылку на аватарку. Для этого в Xamarin.Auth есть специальный класс OAuth2Request с помощью которого удобно делать подобные запросы.

             var request = new OAuth2Request("GET", new Uri("https://apis.live.net/v5.0/me"), null, account);
var response = await request.GetResponseAsync();

Теперь нам приходит JSON с данными пользователя, и мы можем их сохранить и отобразить в приложении.

             if (response.StatusCode == HttpStatusCode.OK)
{
    var userJson = response.GetResponseText();
    var jobject = JObject.Parse(userJson);
    result.LoginState = LoginState.Success;
    result.Email = jobject["emails"]?["preferred"].ToString();
    result.FirstName = jobject["first_name"]?.ToString();
    result.LastName = jobject["last_name"]?.ToString();
    result.ImageUrl = jobject["picture"]?["data"]?["url"]?.ToString();
    var userId = jobject["id"]?.ToString();
    result.UserId = userId;
    result.ImageUrl = $"https://apis.live.net/v5.0/{userId}/picture";
}

Как видим, ничего сложного нет. Вопрос в том, чтобы правильно прописать URL для процесса авторизации. Ну и помнить, что поле expires_in содержит время в секундах (это вызывает частые вопросы).

Авторизация OAuth для Xamarin-приложений - 5

В реальных проектах также рекомендуем назначить обработчик ошибок на событие auth.Error, чтобы ни одна проблема не осталась без решения.

Заключение

Сегодня мы завершили рассмотрение всех популярных способов авторизации пользователей и получения базовой информации о них через внешние сервисы. Описанные механизмы подходят как для Xamarin.Forms, так и для классического Xamarin iOS/Android. Полные исходные коды проекта со всеми примерами можно найти в нашем репозитории:

https://bitbucket.org/binwell/login

Задавайте ваши вопросы в комментариях к статье и оставайтесь на связи!

Об авторе

Авторизация OAuth для Xamarin-приложений - 6 Вячеслав Черников — руководитель отдела разработки компании Binwell, Microsoft MVP и Xamarin Certified Developer. В прошлом — один из Nokia Champion и Qt Certified Specialist, в настоящее время — специалист по платформам Xamarin и Azure. В сферу mobile пришел в 2005 году, с 2008 года занимается разработкой мобильных приложений: начинал с Symbian, Maemo, Meego, Windows Mobile, потом перешел на iOS, Android и Windows Phone. Статьи Вячеслава вы также можете прочитать в блоге на Medium.

Другие статьи автора:

Автор: Microsoft

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js