Статьи

Как аутентифицировать пользователей с помощью API UserVoice на Windows Phone

Мне действительно нравится играть с API uservoice. Это позволяет мне интегрировать множество интересных новых функций, которые выводят пользовательский опыт на новый уровень, помогая мне улучшать свои приложения.

Сегодня я собираюсь написать о том, как аутентифицировать пользователя с помощью API uservoice.

uservoice использует oAuth-аутентификацию в версии 1.0a. Поэтому для нашего приложения нам нужен ключ потребителя и секрет потребителя. Войдите в <yourname> .uservoice.com и перейдите в «Настройки / Интеграция», где вы создадите новый клиент API для своего приложения.

Я рекомендую установить его в качестве доверенного клиента, поскольку у вас будет больше прав с доверенным клиентом. После того, как вы настроите свое приложение, у вас должна появиться такая запись под интеграциями:

uservoice_api_client

Теперь у нас все настроено в части uservoice. Пойдем в наше приложение. Я использую   библиотеку RestSharp, которая немного упрощает аутентификацию пользователей. Вы должны сделать то же самое, если хотите следовать этому посту. В Visual Studio щелкните правой кнопкой мыши имя проекта и выберите «Управление пакетами NuGet», а затем найдите RestSharp в разделе «Онлайн».

После того, как мы интегрируем библиотеку RestSharp в наше приложение, мы собираемся настроить некоторые объекты для аутентификации:

 const string ConsumerKey = "<yourkey>";
 const string ConsumerSecret = "<yoursecret>";
 static string oAuthToken = "";
 static string oAuthTokenSecret = "";
 static string oAuthVerifier = "";
 static string AccessToken = "";
 static string AccessTokenSecret = "";
 const string BaseUrl = "http://<yourname>.uservoice.com";
 const string oAuthCallBackUri = "<yourcallbackUrl>";
 const string requestTokenPath = "oauth/request_token";
 const string authorizePath = "/oauth/authorize?";
 const string accessTokenPath = "oauth/access_token";

Настройка этих статических и константных строковых объектов необходима для нашего потока аутентификации.

Затем добавьте элемент управления WebBrowser в XAML. Нам нужно это, чтобы позволить пользователю авторизовать наше приложение для связи с серверами пользовательских голосов:

<Grid x:Name="authBrowserGrid" Visibility="Collapsed">
 <phone:WebBrowser x:Name="authBrowser" Height="800" Width="460"></phone:WebBrowser>
 </Grid>

Возможно, вы заметили, что я установил свойство Visibility свернутым. С oAuth мы, как правило, аутентифицируем пользователей, направляя их на веб-сайт, который обрабатывает процесс входа для нас. После того, как пользователь авторизовал наше приложение, веб-сайт передает пользователя по нашему URL обратного вызова, который мы определяем нашим клиентом API.

Как я уже говорил выше, RestSharp нам очень помогает, когда дело доходит до аутентификации.

Существует несколько способов использования API RestSharp, но на данный момент я использую его непосредственно для аутентификации своих пользователей.

Это метод запуска:

public void GetUserAuthenticated()
 {

            authBrowserGrid.Visibility = Visibility.Visible;

            var client = new RestClient(BaseUrl)
 {
 Authenticator = OAuth1Authenticator.ForRequestToken(ConsumerKey, ConsumerSecret, oAuthCallBackUri)
 };

            var request = new RestRequest(requestTokenPath, Method.GET);
 var response = client.ExecuteAsync(request, HandleRequestTokenResponse);
 }

Мы создаем новый RestClient, который вызывает наш BaseUrl, который мы определили ранее. В том же вызове мы говорим нашему клиенту, что мы хотим использовать oAuth 1.0 (a), передавая параметры ConsumerKey, ConsumerSecret и наш URL обратного вызова с клиентом. Поскольку мы хотим получить RequestToken, мы генерируем новый RestRequest, передавая requestTokenPath и метод ‘GET’ в качестве параметров.

Наконец, мы хотим продолжить с ответом, который должен содержать наш RequestToken. Windows Phone поддерживает только метод ExecuteAsync, для выполнения которого требуется определенный обработчик ответа. Это был первый урок, который мне пришлось выучить с помощью RestSharp на Windows Phone. Чтобы обработать ответ, мы создаем новый метод-обработчик, который реализует IRestResponse:

private void HandleRequestTokenResponse(IRestResponse restResponse)
 {
    var response = restResponse;

          //tbd: write an extraction helper for all tokens, verifier, secrets
 oAuthToken = response.Content.Substring((response.Content.IndexOf("oauth_token=") + 12), (response.Content.IndexOf("&oauth_token_secret=") - 12));
 var tempStringForGettingoAuthTokenSecret = response.Content.Substring(response.Content.IndexOf("&oauth_token_secret=") + 20);
 oAuthTokenSecret = tempStringForGettingoAuthTokenSecret.Substring(0,  tempStringForGettingoAuthTokenSecret.IndexOf("&oauth_callback_confirmed"));

var authorizeUrl = string.Format("{0}{1}{2}",BaseUrl, authorizePath, response.Content);

           authBrowser.Navigate(new Uri(authorizeUrl));
 authBrowser.IsScriptEnabled = true;
 authBrowser.Navigating += authBrowser_Navigating;

}

Теперь у нас есть объект, с которым мы можем работать (переменная response). Нам нужно извлечь oauth_token и oauth_token_secret и сохранить их для дальнейшего использования.

После этого мы можем создать наш URL авторизации, который мы передадим элементу управления WebBrowser, который мы создали ранее. Важное замечание: для свойства IsScriptEnabled следует установить значение true, поскольку веб-сайты аутентификации часто используют сценарии для проверки введенных данных. И последнее, но не менее важное: мы подписываемся на событие Navigating элемента управления браузера. В этом случае мы обрабатываем ответ на авторизацию:

void authBrowser_Navigating(object sender, NavigatingEventArgs e)
 {
      if (e.Uri.AbsolutePath == "<yourAbsolutePath>")
      {
           oAuthVerifier = e.Uri.Query.Substring(e.Uri.Query.IndexOf("&oauth_verifier=") + 16);

           GetAccessToken();
      }
 }

Нам нужна строка подтверждения только для следующего запроса, который мы должны отправить, поэтому мы извлекаем параметр «oauth_verifier» и переходим, чтобы получить AccessToken для всех дальнейших запросов:

private void GetAccessToken()
 {
 var client = new RestClient(BaseUrl)
 {
 Authenticator = OAuth1Authenticator.ForAccessToken(ConsumerKey, ConsumerSecret, oAuthToken, oAuthTokenSecret, oAuthVerifier)
 };

            var request = new RestRequest(accessTokenPath, Method.GET);
 var response = client.ExecuteAsync(request, HandleAccessTokenResponse);

        }

На этот раз мы говорим нашему RestClient, что мы хотим получить AccessToken, и нам также нужны oAuthToken и oAuthTokenSecret, которые мы сохранили, прежде чем мы переместили наших пользователей на сайт аутентификации по uservoice. Конечно, нам также нужен обработчик для ответа на этот запрос:

private void HandleAccessTokenResponse(IRestResponse restResponse)
 {
 var response = restResponse;

            AccessToken = response.Content.Substring(12, response.Content.IndexOf("&oauth_token_secret=") -12);
 AccessTokenSecret = response.Content.Substring(response.Content.IndexOf("&oauth_token_secret=") + 20);

            authBrowserGrid.Visibility = Visibility.Collapsed;

            //continue with your code (new method call etc.)
 }

Единственное, что нам теперь нужно сделать, — это извлечь AccessToken и AccessTokenSecret и сохранить их навсегда в нашем приложении (до тех пор, пока пользователь аутентифицирован). Они нужны нам для большого количества вызовов API uservoice.

Давайте вызовем API uservoice для получения дополнительной информации о пользователе, который теперь авторизовал наше приложение:

public void GetUser()
 {
 var client = new RestClient(BaseUrl)
 {
 Authenticator = OAuth1Authenticator.ForProtectedResource(ConsumerKey, ConsumerSecret, AccessToken, AccessTokenSecret)
 };

           var request = new RestRequest(getUserPath, Method.GET);
 var response = client.ExecuteAsync(request, HandleGetUserResponse);
 }

Как вы можете видеть, мы теперь используем только AccessToken и AccessTokenSecret для вызова API-интерфейса uservoice, дополнительный вход в систему не требуется. Чтобы завершить этот пример, вот снова обработчик ответа:

private void HandleGetUserResponse(IRestResponse restResponse)
       {
              var response = restResponse;

            //tbd: do something with the result (e.g. checking response.StatusCode)

       }

Теперь мы получили строку JSON, которая сообщает нам много информации о нашем пользователе и дате, которую мы имеем в uservoice:

Снимок экрана (304)

Как видите, сравнительно легко аутентифицировать наших пользователей и вызывать API uservoice. В моем следующем посте я напишу о предложениях (это идея форума). Я подробно расскажу о том, как получить список всех предложений, о том, как позволить пользователю опубликовать новую идею и позволить ему голосовать за идеи — и все это из вашего приложения!

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

Удачного кодирования всем!