Невозможно использовать Java Signpost для правильного OAuth (с Discogs)

Я пытаюсь использовать Java SignPost, чтобы получить поддержку Oauth от Discogs

Если я вызываю этот метод, он предоставляет URL для веб-сайта, а затем, когда я вхожу в систему, я получаю проверочный код, пока все хорошо.

    public static String requestDiscogsAuthorization() throws Exception
    {

        OAuthConsumer consumer = new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
        OAuthProvider provider = new DefaultOAuthProvider(
                "http://api.discogs.com/oauth/request_token",
                "http://api.discogs.com/oauth/access_token",
                "http://www.discogs.com/oauth/authorize");
        provider.setRequestHeader("User-Agent", SongKong.USER_AGENT);
        return provider.retrieveRequestToken(consumer,  OAuth.OUT_OF_BAND);
    }

Я сохраняю этот код подтверждения в своем приложении и могу получить его как UserPreferences.getInstance(). GetDiscogsAuthorization(). Итак, теперь я хочу подписать URL-адрес, который я пытаюсь вызвать getAccessToken() ниже, чтобы получить код доступа из моего ключа подтверждения, но я получаю

oauth.signpost.exception.OAuthExpectationFailedException: Authorized request token or token secret not set. Did you retrieve an authorized request token before?
    at oauth.signpost.AbstractOAuthProvider.retrieveAccessToken(AbstractOAuthProvider.java:89)
    at com.jthink.songkong.analyse.toplevelanalyzer.DiscogsAuth.getAccessToken(DiscogsAuth.java:54)

Я не вижу, что я делаю не так

 public class DiscogsAuth
{
    /**
     * Constructs a consumer with valid access token for signing urls (can only be used once user has authorizaed application and auth code
     * available to application somewhere
     *
     * NOTE:Not thread safe, has to be done once for each thread
     *
     * @return
     * @throws Exception
     */
    public static OAuthConsumer getAccessToken() throws Exception
    {
        OAuthConsumer consumer = new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
        OAuthProvider provider = new DefaultOAuthProvider(
                "http://api.discogs.com/oauth/request_token",
                "http://api.discogs.com/oauth/access_token",
                "http://www.discogs.com/oauth/authorize");
        provider.setRequestHeader("User-Agent", SongKong.USER_AGENT);
        provider.retrieveAccessToken(consumer, UserPreferences.getInstance().getDiscogsAuthorization());
        return consumer;
    }

    /**
     * Sign Url Connection
     *
     * @param urlConnection
     * @param consumer
     * @throws Exception
     */
    public static void signUrl(HttpURLConnection urlConnection, OAuthConsumer consumer) throws Exception
    {
         consumer.sign(urlConnection);
    }
}

3 ответа

Решение

Проблема заключалась в том, что я не использовал один и тот же экземпляр OAuthConsumer и OAuthProvider для каждого шага.

Возможно, вызов вашего метода не смог получить код подтверждения, когда вы пытаетесь вызвать provider.retrieveAccessToken, вы можете попытаться распечатать код подтверждения, прежде чем передать его в метод provider.retrieveAccessToken.

Вам не хватает токена доступа и секрета токена доступа.

Чтобы подписать запрос OAuth 1.0, вам нужны три вещи: CONSUMER_SECRET что у вас уже есть, токен доступа и секрет токена доступа, который вы получите в oauth_token а также oauth_token_secret переменные соответственно в ответе на запрос временных учетных данных.

У меня нет опыта работы с Java, но в соответствии с документацией Signpost, я думаю, вы должны назвать это...

consumer.setTokenWithSecret(ACCESS_TOKEN, TOKEN_SECRET);

... прежде чем пытаться подписать URL

consumer.sign(urlConnection);

Похоже, вы можете получить ACCESS_TOKEN а также TOKEN_SECRET с...

String accessToken = provider.getResponseParameter('oauth_token');
String tokenSecret = provider.getResponseParameter('oauth_token_secret');

... после того, как вы позвоните это:

provider.retrieveAccessToken(consumer, verificationCode);

Вот мое мнение (я не пробовал):

 public class DiscogsAuth
{
    /**
     * Constructs a consumer with valid access token for signing urls (can only be used once user has authorizaed application and auth code
     * available to application somewhere
     *
     * NOTE:Not thread safe, has to be done once for each thread
     *
     * @return
     * @throws Exception
     */
    public static OAuthConsumer getAccessToken() throws Exception
    {
        OAuthConsumer consumer = new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
        OAuthProvider provider = new DefaultOAuthProvider(
                "http://api.discogs.com/oauth/request_token",
                "http://api.discogs.com/oauth/access_token",
                "http://www.discogs.com/oauth/authorize");
        provider.setRequestHeader("User-Agent", SongKong.USER_AGENT);
        provider.retrieveAccessToken(consumer, UserPreferences.getInstance().getDiscogsAuthorization());

        // Retrieve access token and access token secret
        String accessToken = provider.getResponseParameter('oauth_token');
        String tokenSecret = provider.getResponseParameter('oauth_token_secret');

        // Set them on the consumer so it can sign the requestst with them
        consumer.setTokenWithSecret(accessToken, tokenSecret);

        return consumer;
    }

    /**
     * Sign Url Connection
     *
     * @param urlConnection
     * @param consumer
     * @throws Exception
     */
    public static void signUrl(HttpURLConnection urlConnection, OAuthConsumer consumer) throws Exception
    {
         consumer.sign(urlConnection);
    }
}
Другие вопросы по тегам