Мне действительно нравится играть с API uservoice. Это позволяет мне интегрировать множество интересных новых функций, которые выводят пользовательский опыт на новый уровень, помогая мне улучшать свои приложения.
Сегодня я собираюсь написать о том, как аутентифицировать пользователя с помощью API uservoice.
uservoice использует oAuth-аутентификацию в версии 1.0a. Поэтому для нашего приложения нам нужен ключ потребителя и секрет потребителя. Войдите в <yourname> .uservoice.com и перейдите в «Настройки / Интеграция», где вы создадите новый клиент API для своего приложения.
Я рекомендую установить его в качестве доверенного клиента, поскольку у вас будет больше прав с доверенным клиентом. После того, как вы настроите свое приложение, у вас должна появиться такая запись под интеграциями:
Теперь у нас все настроено в части 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:
Как видите, сравнительно легко аутентифицировать наших пользователей и вызывать API uservoice. В моем следующем посте я напишу о предложениях (это идея форума). Я подробно расскажу о том, как получить список всех предложений, о том, как позволить пользователю опубликовать новую идею и позволить ему голосовать за идеи — и все это из вашего приложения!
В то же время, я надеюсь, что этот пост будет полезен для некоторых из вас.
Удачного кодирования всем!