#android #oauth #tumblr #signpost
#Android #oauth #tumblr #указатель
Вопрос:
Итак, я создаю клиент Tumblr для Android, я пытаюсь и не могу заставить OAuth работать уже около недели. Вот как это происходит:
Пользователь запускает приложение. onCreate основного действия делает это:
settings = getSharedPreferences(PREFS_NAME, 0);
authToken=settings.getString("OauthToken", "none");
authTokenSecret=settings.getString("OauthSecret", "none");
if(authToken=="none" || authTokenSecret=="none"){
Intent i = new Intent(getApplicationContext(),Authentication.class);
startActivity(i);
}
это запускает действие аутентификации, которое содержит WebView. Это действие успешно получает токен запроса и отправляет WebView на экран входа в систему Tumblr. Пользователю предлагается разрешить доступ к своим данным с помощью приложения, они нажимают Разрешить, и мой WebViewClient перехватывает URL обратного вызова и делает это с ним:
String[] token = helper.getVerifier(url);
if (token != null) {
try {
String accessToken[] = helper.getAccessToken(token[1]);
editor.putString("OauthToken", accessToken[0]);
editor.putString("OauthSecret", accessToken[1]);
editor.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
finish();
getAccessToken и getVerifier вспомогательного класса выглядят следующим образом:
public String[] getVerifier(String myUrl) {
// extract the token if it exists
Uri uri = Uri.parse(myUrl);
if (uri == null) {
return null;
}
String token = uri.getQueryParameter("oauth_token");
String verifier = uri.getQueryParameter("oauth_verifier");
return new String[] { token, verifier };
}
public String[] getAccessToken(final String verifier)
throws OAuthMessageSignerException, OAuthNotAuthorizedException,
OAuthExpectationFailedException, OAuthCommunicationException {
new Thread(new Runnable() {
public void run() {
try {
mProvider.retrieveAccessToken(mConsumer, verifier);
} catch (OAuthMessageSignerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OAuthNotAuthorizedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OAuthCommunicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
return new String[] {
mConsumer.getToken(), mConsumer.getTokenSecret()
};
}
Затем я, наконец, возвращаюсь к главному экрану приложения и пытаюсь выполнить свой первый вызов API, чтобы получить самые последние десять сообщений на панели управления пользователя:
OAuthConsumer myConsumer = new CommonsHttpOAuthConsumer(MainView.authToken, MainView.authTokenSecret);
HttpGet request = new HttpGet("http://api.tumblr.com/v2/user/dashboard?limit=10");
myConsumer.sign(request);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);
HttpEntity entity = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
Однако вместо того, чтобы получить хороший ответ JSON, каким я должен быть, я получаю это:
10-20 16:36:18.110: D/Result(22817): {"meta":{"status":401,"msg":"Not Authorized"},"response":[]}
Итак, где я ошибся? Спасибо
Комментарии:
1. Я получаю точно такую же проблему, когда пытаюсь использовать методы API, требующие запросов POST, однако запросы GET, похоже, работают нормально. Я начинаю задаваться вопросом, не является ли их API немного ненадежным.
2. На какой версии Android вы разрабатываете?
3. Я также не могу получить информацию о пользователе, событие после получения токена и секрет: (было бы здорово, если бы кто-нибудь мог дать решение для этого.
Ответ №1:
Я успешно использовал библиотеку указателей с помощью Appache HttpCommons GET / POST / PUTs.
Во-первых, я запустил WebView для входа в систему, используя следующий код ( ActivityLogin.java
):
private static CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(AppConfig.CONSUMER_KEY, AppConfig.CONSUMER_SECRET);
private static OAuthProvider provider = new DefaultOAuthProvider (AppConfig.requestURL, AppConfig.accessURL, AppConfig.authURL);
private void logMeIn() throws ...{
String authUrl = provider.retrieveRequestToken(consumer,AppConfig.CALLBACK_URL);
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
}
Затем я использовал onNewIntent(Intent)
для получения обратных вызовов OAuth из ранее запущенного Activity
:
AppConfig.java
снипет кода:
/** OAuth Authorization URL */
public static final String authURL = mainOAuthUrl "/authorize/?theme=android";
/** OAuth Request URL */
public static final String requestURL = mainOAuthUrl "/request/token/";
/** OAuth Access URL */
public static final String accessURL = mainOAuthUrl "/access/token/";
/** OAuth CALLback URL*/
public static final String CALLBACK_URL = "yourapp://twitt";
ActivityLogin.java
снипет кода:
protected void onNewIntent(Intent intent) {
Uri uri = intent.getData();
if (uri != null amp;amp; uri.toString().startsWith(AppConfig.CALLBACK_URL)) {
String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
provider.retrieveAccessToken(consumer, verifier);
Data.OAuthAccessKey = consumer.getToken();
Data.OAuthAccessSecret = consumer.getTokenSecret();
}
}
И тогда мой код подключения выглядит так:
public HttpResponse sampleOauthConnect(String url) throws ...{
/** setup some connection params */
HttpContext context = new BasicHttpContext();
HttpRequestBase request = new HttpGet(url);
if (Data.OAuthConsumer == null)
Data.OAuthConsumer = new CommonsHttpOAuthConsumer(AppConfig.CONSUMER_KEY, AppConfig.CONSUMER_SECRET);
if (Data.OAuthAccessKey == null || Data.OAuthAccessSecret == null)
throw new LoginErrorException(LoginErrorException.NOT_LOGGED_IN);
Data.OAuthConsumer.setTokenWithSecret(Data.OAuthAccessKey, Data.OAuthAccessSecret);
try {
Data.OAuthConsumer.sign(request);
} catch (OAuthMessageSignerException e) {
throw new LoginErrorException(LoginErrorException.OAUTH_EXCEPTION, e);
} catch (OAuthExpectationFailedException e) {
throw new LoginErrorException(LoginErrorException.OAUTH_EXCEPTION, e);
} catch (OAuthCommunicationException e) {
throw new LoginErrorException(LoginErrorException.OAUTH_EXCEPTION, e);
}
HttpClient client = new DefaultHttpClient();
/** finally execute this request */
return client.execute(request, context);
}
Возможно, я что-то пропустил во время копирования-вставки, просто скажите мне, будет ли это решение работать для вас. Я использую singpost 1.2.1.1
Комментарии:
1. У меня нет времени тестировать ваш код прямо сейчас или даже в течение следующих нескольких дней. Но поскольку вознаграждение заканчивалось, и это выглядит как очень полезный подробный пост, вы выиграли! Спасибо, я узнаю, действительно ли это работает позже
2. Имейте в виду, что я использую две пары ключей прямо здесь:
AppConfig.CONSUMER_KEY, AppConfig.CONSUMER_SECRET
(которые хранятся в приложении) иData.OAuthAccessKey, Data.OAuthAccessSecret
которые генерируются сервером.3. получение того же ответа неавторизовано: {«meta»:{«status»:401, «сообщение»: «Не авторизовано»}, «ответ»:[]}
4. вот полное руководство по входу в Tumblr с помощью signpost в Android: android-ios-tutorials.com/920/tumblr-login-using-sign-post
Ответ №2:
В настоящее время Tumblr не поддерживается MultipartEntity
, поэтому вам нужно использовать NameValuePairs
для добавления параметров.
Если вы хотите опубликовать фотографию, вы ДОЛЖНЫ преобразовать эту фотографию в МАССИВ и закодировать ее по URL-адресу!
Комментарии:
1. Столкнулся с проблемой публикации фотографий. Что вы имеете в виду, говоря «… преобразовать эту фотографию в МАССИВ и кодировать ее по URL»? Не могли бы вы предоставить какой-нибудь фрагмент кода.
2. Собственная библиотека Tumbler (Jumblr) использует составные формы: github.com/tumblr/jumblr/blob/master/src/main/java/com/tumblr /…