Авторизация ВКонтакте для приложения на iOS (Monotouch)

Аутентификация ВКонтакте происходит по протоколу OAuth 2.0. О том, что это за протокол и что такое аутентификация и авторизация пост ранее "Аутентификация и авторизация, OpenID и OAuth".  Будем реализовывать Client-Side (Implicit) Authentication. Это означает, что в ходе аутентификации пользователь вводит свои данные на сайте vk.com, а приложение получает некий Access Token, позволяющий выполнять разрешенные (авторизованные) действия по этому токену.

Для начала создаем приложение (тип standalone-приложение). После создания приложения необходимо записать AppID в приложение. Secret key в таком типе аутентификации не требуется. Общий класс для API представлен ниже.

public class VKApi
{
    public const int VKAppID = 4127216;

    /// <summary>
    /// 0 - Method
    /// 1 - Access Token
    /// 2 - Params
    /// </summary>
    public const string APIURLTemplate = "https://api.vk.com/method/{0}?v=5.5&access_token={1}&{2}";

    public static string GenerateAuthURL()
    {
        return "https://oauth.vk.com/authorize?client_id=" + VKAppID +
            "&scope=friends,photos,status,wall,messages,offline&" +
        "redirect_uri=https://oauth.vk.com/blank.html&" +
        "display=mobile&" +
        "v=5.5&response_type=token";
    }
}

Для авторизации создадим класс VKAuthScreen, в котором опишем логику авторизации пользователей на сайте vk.com.

using System;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using MonoTouch.UIKit;
using MonoTouch.Foundation;


namespace Solution
{
    public class VKAuthScreen : BaseScreen
    {
        private UIWebView _browser;

        public VKAuthScreen() : base("ВКонтакте")
        {
            ShowBackButton = true;
        }


        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            foreach (var cookie in NSHttpCookieStorage.SharedStorage.Cookies)
            {
                NSHttpCookieStorage.SharedStorage.DeleteCookie(cookie);
            }
            NSUserDefaults.StandardUserDefaults.Synchronize();

            _browser = new UIWebView();
            _browser.LoadFinished += LoadFinished;
            _browser.Frame = new RectangleF(new PointF(0, 0), RootView.Frame.Size);

            RootView.AddSubview(_browser);

            NSUrl nsurl = new NSUrl(VKApi.GenerateAuthURL());
            NSUrlRequest req = new NSUrlRequest(nsurl);
            _browser.LoadRequest(req);
        }

        private async void LoadFinished(object sender, EventArgs e)
        {

            string url = _browser.Request.Url.AbsoluteString;
            if (string.IsNullOrEmpty(url))
                return;

            url = url.ToLower();

            if (url.Contains("#access_token"))
            {
                string accessToken = "";
                long userId = 0;
                Regex myReg = new Regex(@"(?<name>[\w\d\x5f]+)=(?<value>[^\x26\s]+)", 
                                  RegexOptions.IgnoreCase | RegexOptions.Singleline);
                foreach (Match m in myReg.Matches(url))
                {
                    if (m.Groups["name"].Value == "access_token")
                    {
                        accessToken = m.Groups["value"].Value;
                    }
                    else if (m.Groups["name"].Value == "user_id")
                    {
                        userId = Convert.ToInt64(m.Groups["value"].Value);
                    }
                }

                //Успех
                if (!string.IsNullOrEmpty(accessToken) && userId > 0)
                {
                    // Записываем токен и идентификатор пользователя
                    // ...                  
                }

            }
        }
    }
}

В моем случае необходимо очистить Cookies перед открытием страницы в браузере (чтобы была возможность авторизовывать несколько аккаунтов в приложении одновременно). 

 

Комментарии

comments powered by Disqus