[Из песочницы] Flickr API в Android App. Авторизация

Привет, хабралюди! Хочу поделиться с вами небольшим опытом использования Flickr API в Android приложениях и рассказать об авторизации пользователя Flickr. Которую в дальнейшем можно будет использовать например для вывода списка альбомов и изображений.

Регистрация приложенияПервым делом нам нужно получить API Key, приложения будем использовать не в коммерческих целях, для регистрации переходим по ссылке Create an App.ad4d777aed3e4e59a0629c6306a4e12a.jpg

Нас просят ввести «Название», «Цель» и «Соглашения с правами», отправляем наши данные и в результати получаем API Key и API Secret. Они нужны нам в дальнейшем для формирования запроса к серверу.

52f4999dd727413fbfc854abfcff8d0f.jpg

После этого нам нужно редактировать некоторые данные, в этом же окне переходим на Edit auth flow for this app.

a861604b5dd0473bb9bcad1d69cd5ac9.jpg

Описания и логотип нам не интересны, вводить можете по желанию. В поле Callback URL нам обязательно нужно задать адрес обратного вызова, который мы будем использовать для возвращения к нашему Activity. В моем случае я задаю appforflickr://callback. В болке это буде выглядеть следующим образом:

… App Type — выбираем Web Application и Сохраняем изменения.Далее переходим непосредственно к построения самого приложения.

В манифесте приложения добавляем «android.permission.INTERNET» и блок в результате получаем:

Создание ссылки для авторизации пользователя Для авторизации пользователей в приложении мы будем запускать Activity с WebView. Но сначала сформируем адрес для входа. Шаблон выглядет следующим образом: http://flickr.com/services/auth/? api_key=[api_key]&perms=[perms]&api_sig=[api_sig] [api_key] — это наш ключ полученый при регистрации приложения. [perms] — уровень доступа к аккаунту, может принимать следующие значения: read — разрешения на чтения личной информации write — разрешения на добавления и редактирования фотографий и информации (включает в себя 'read') delete — разрешения на удаления фотографий (включает в себя 'read' и 'write ') [api_sig] — подпись, она включает в себя Secret полученый при регистрации приложения и список аргументов в алфавитном порядке, имя и значения.В нашем случае API Key: 5744fadec815a7e8142d03901065c97b, API Secret: 8b2c12e80b67970b, права доступа write, подпись это строка из: secret + 'api_key' + [api_key] + 'perms' + [perms] , то есть мы имеем: 8b2c12e80b67970bapi_key5744fadec815a7e8142d03901065c97bpermswrite и теперь нужно зашифровать эту строку в MD5. Для этого используем следующий метод: public static final String md5SumOfString (final String s) { try { MessageDigest digest = java.security.MessageDigest.getInstance («MD5»); digest.update (s.getBytes ()); byte messageDigest[] = digest.digest ();

StringBuffer hexString = new StringBuffer (); for (int i = 0; i < messageDigest.length; i++) hexString.append(Integer.toHexString(0xFF & messageDigest[i])); return hexString.toString();

} catch (NoSuchAlgorithmException e) { e.printStackTrace (); } return »; } и получем значения [api_sig].В итоге адрес для авторизация пользователя будет выглядеть следующим образом:

http://www.flickr.com/services/auth/? api_key=9a0554259914a86fb9e7eb014e4e5d52&perms=write&api_sig=b8d7c1ae026d5f86f1f44944f5257f3 В onCreate () добавляем startActivity (new Intent (Intent.ACTION_VIEW, Uri.parse (url))); , где url — это вышеуказанный адрес. После запуска приложения мы открываем веб-страницу, чтобы указать логин и пароль. Если введеные данные будут верны нас по Callback URL автоматически перенаправит на наше приложеня. К url добавляеться параметр frob из значениям, то есть в нашем случае это выглядит так: appforflickr://callback? frob=72157650137623777-b09eae52121bf8ad-130818926 Frob нужен для получения Access token.Добавим условия в onCreate (), чтобы получить frob: Uri uri = getIntent ().getData (); if (uri!= null) { String frob = uri.getQueryParameter («frob»); } else startActivity (new Intent (Intent.ACTION_VIEW, Uri.parse (url))); После того обработки вызываем метод flickr.auth.getToken из API для получения token и nsid, которые понадобятся для дальнейших запросов, а так же username и fullname пользователя.Для отправки запросов создадим class HttpRequest:

public class HttpRequest extends AsyncTask {

public static final String TAG = HttpRequest.class.getSimpleName ();

@Override protected void onPreExecute () { Log.d (TAG, «START»); }

@Override protected String doInBackground (String… params) { String result = »; try { String uri = params[0]; HttpGet httpGet = new HttpGet (uri); HttpResponse response = HttpClientHelper.getHttpClient ().execute (httpGet); HttpEntity entity = response.getEntity (); if (entity!= null) { InputStream inStream = entity.getContent (); result = InputStreamConverter.convertStreamToString (inStream); inStream.close (); } return result; } catch (IllegalStateException e) { return result; } catch (ClientProtocolException e) { return result; } catch (IOException e) { return result; } }

@Override protected void onPostExecute (String result) { Log.d (TAG, «STOP»); } } Class HttpClientHelper для получения HttpClient:

public class HttpClientHelper {

private static HttpClient httpClient = null; private static final int REGISTRATION_TIMEOUT = 30×1000; private static final int WAIT_TIMEOUT = 30×1000;

private HttpClientHelper () {}

public static synchronized HttpClient getHttpClient () { if (httpClient == null) { HttpParams params = new BasicHttpParams (); HttpProtocolParams.setVersion (params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset (params, HTTP.DEFAULT_CONTENT_CHARSET); HttpProtocolParams.setUseExpectContinue (params, true); ConnManagerParams.setTimeout (params, WAIT_TIMEOUT); HttpConnectionParams.setConnectionTimeout (params, REGISTRATION_TIMEOUT); HttpConnectionParams.setSoTimeout (params, WAIT_TIMEOUT); SchemeRegistry schemeReg = new SchemeRegistry (); schemeReg.register (new Scheme («http», PlainSocketFactory.getSocketFactory (), 80)); schemeReg.register (new Scheme («https», SSLSocketFactory.getSocketFactory (), 443)); ClientConnectionManager connectionMgr = new ThreadSafeClientConnManager (params, schemeReg); httpClient = new DefaultHttpClient (connectionMgr, params); } return httpClient; } } Class InputStreamConverter для конвертации InputStream в String:

public class InputStreamConverter {

private InputStreamConverter () {}

public static String convertStreamToString (InputStream inputStream) { BufferedReader reader = new BufferedReader (new InputStreamReader (inputStream)); StringBuilder builder = new StringBuilder (); String line = null; try { while ((line = reader.readLine ()) != null) { builder.append (line + »\n»); } } catch (IOException e) { e.printStackTrace (); } finally { try { inputStream.close (); } catch (IOException e) { e.printStackTrace (); } } return builder.toString (); } } Адрес для получения token:

https://api.flickr.com/services/rest/? method=flickr.auth.getToken&api_key=9a0554259914a86fb9e7eb014e4e5d52&frob=72157650137623777-b09eae52121bf8ad-130818926&format=json&nojsoncallback=1&perms=write&api_sig=8fd09b55f670ec9a4ba07c076e520ae8 , чтобы ответ пришел в виде json мы добавили пераметры из значениями format=json и nojsoncallback=1Вносим еще раз изминения в onCreate () для отправки запроса:

Uri uri = getIntent ().getData (); if (uri!= null) { String frob = uri.getQueryParameter («frob»); String url = »…»; // Наш сформированый адрес для получения token String response = »; HttpRequest httpRequest = new HttpRequest (this); httpRequest.execute (url); try { response = httpRequest.get (); } catch (InterruptedException | ExecutionException e) { e.printStackTrace (); } } else startActivity (new Intent (Intent.ACTION_VIEW, Uri.parse (url))); Далее полученый ответ:

{«auth»:{«token»:{»_content»:»12134650097774510–014feda8303a4a64»}, «perms»:{»_content»: «write»}, «user»:{«nsid»:»230211065@N05», «username»: «user», «fullname»: «User Alex»}}, «stat»: «ok»} можна розпарсить получить желанный token и nsid при помощи таких библиотек как gson или jackson это уже на любителя.Надеюсь моя статья будет кому-то полезна.

PS. Это мой первый пост на Хабре, так что извините за немногословность и не судите строго.

© Habrahabr.ru