Как создать запрос oAuth с помощью java?

Мне нужно установить соединение с веб-сайтом Viagogo с помощью oAuth. Ссылаясь на их документацию, мне нужно создать запрос, подобный следующему один

Using the example in step 1A, this means you may generate a signature base string that looks like the following:

GET&http%3A%2F%2Fapi.viagogo.net%2FPublic%2FSimpleOAuthAccessRequest&oauth_consumer_key%3Dtestkey%26oauth_nonce%3Dmyn0nc3%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1292404912%26oauth_version%3D1.0%26scope%3DAPI.Public

Я использую следующий код, но когда я комментирую строки 1 и 2, он возвращает unauthorized error, а когда я их использую, он показывает, что oauthService.signRequest возвращает void.

TradeKingAPI.java

import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.Token;

public class TradeKingAPI extends DefaultApi10a {
    @Override
    public String getRequestTokenEndpoint() {
        return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
    }
    @Override
    public String getAccessTokenEndpoint() {
        return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
    }
    @Override
    public String getAuthorizationUrl(Token requestToken) {
        return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
    }
}

main.java

import org.scribe.builder.ServiceBuilder;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;

import api.TradeKingAPI;
import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.OAuthConstants;
import org.scribe.oauth.OAuthService;

   ........

    OAuthService oauthService = new ServiceBuilder()
            .provider(TradeKingAPI.class)
            .apiKey("My consumer key")
            .apiSecret("My secret")
            .scope("API.Public")
            .build();

    Long seconds = (System.currentTimeMillis() / 1000);
    System.out.println(">>>" + seconds);
    String stSeconds = seconds.toString();
    OAuthRequest request = new OAuthRequest(Verb.GET, "http://api.viagogo.net/Public
                                                                     /SimpleOAuthAccessRequest");

    request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, "My consumer key");
    request.addOAuthParameter(OAuthConstants.NONCE, "myn0nc3");
    request.addOAuthParameter(OAuthConstants.SIGN_METHOD, "HMAC-SHA1");
    request.addOAuthParameter(OAuthConstants.TIMESTAMP, seconds.toString());
    request.addOAuthParameter(OAuthConstants.VERSION, "1.0");
    request.addOAuthParameter("scope", "API.Public");

 1  String signature = oauthService.signRequest(OAuthConstants.EMPTY_TOKEN, request);

 2  request.addOAuthParameter(OAuthConstants.SIGNATURE,signature);
    Response response = request.send();
    System.err.println(">>" + response.isSuccessful());
    System.err.println(">>" + response.getMessage());
    System.err.println(">>" + response.getBody());

person J888    schedule 18.07.2013    source источник
comment
Вы искали и, возможно, нашли Похожие вопросы   -  person Mgetz    schedule 18.07.2013
comment
Почему бы не использовать существующие библиотеки Java OAuth?   -  person Buhake Sindi    schedule 18.07.2013
comment
@BuhakeSindi Я ничего не нашел, не могли бы вы привести пример? или укажите мне учебник, пожалуйста, спасибо.   -  person J888    schedule 19.07.2013
comment
@Mgetz сталкивался с этим раньше, но предпочитает делать это автоматически, поскольку для ответа требуется много строк кода.   -  person J888    schedule 19.07.2013
comment
@JackRamzi, их немного, например Scribe или JOAuth и многие другие.   -  person Buhake Sindi    schedule 19.07.2013
comment
@BuhakeSindi Я использую писца в своем вопросе!   -  person J888    schedule 20.07.2013


Ответы (2)


Насколько я понимаю из документации по общедоступному API Viagogo, токен, который вы получаете на шаге 1, эквивалентен токену запроса в полном «танце» OAuth 1.0a.

Таким образом, вы должны иметь возможность использовать внутренние классы scribe-java, чтобы получить этот токен, не делая это вручную. Единственное отличие состоит в том, что в писце этот запрос также отправляет URL-адрес обратного вызова на сервер OAuth для следующего шага «танца» OAuth.

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

Сценарий 1: сервер Viagogo допускает дополнительный параметр (например, URL-адрес обратного вызова)

так что вы можете пойти с этим кодом

import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.Token;

public class TradeKingAPI extends DefaultApi10a {

    @Override
    public Verb getRequestTokenVerb()
    {
      return Verb.GET;
    }

    @Override
    public String getRequestTokenEndpoint() {
        return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
    }

    @Override
    public String getAccessTokenEndpoint() {
        return "none";
    }

    @Override
    public String getAuthorizationUrl(Token requestToken) {
        return "none";
    }
}

Тогда ваш код вызова будет:

OAuthService service = new ServiceBuilder()
                            .provider(TradeKingAPI.class)
                            .signatureType(QueryString)
                            .apiKey("My consumer key")
                            .apiSecret("My secret")
                            .scope("API.Public")
                            .build();

Token requestToken = service.getRequestToken();

//make your API calls

OAuthRequest request = new OAuthRequest(Verb.GET,
                       "http://api.viagogo.net/Public/Event/235");
service.signRequest(requestToken, request);
Response response = request.send();
System.out.println(response.getBody());

Но, как я уже сказал, если безопасность Viagogo немного строга и он отказывается от бесполезного параметра oauth_callback, вам нужно переключиться на сценарий 2.

Сценарий 2. Создайте свой собственный OAuthService.

В этом сценарии вам нужно создать новый OAuthService, чтобы не иметь дело с параметром OAuthCallback.

import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.*;
import org.scribe.oauth.OAuth10aServiceImpl;

import java.util.Map;

public class OAuth10aServiceForViagogo extends OAuth10aServiceImpl {

    private OAuthConfig config;
    private DefaultApi10a api;

    public OAuth10aServiceForViagogo(DefaultApi10a api, OAuthConfig config) {
        super(api, config);

        this.api = api;
        this.config = config;
    }

    private void addOAuthParams(OAuthRequest request, Token token) {
        request.addOAuthParameter(OAuthConstants.TIMESTAMP, api.getTimestampService().getTimestampInSeconds());
        request.addOAuthParameter(OAuthConstants.NONCE, api.getTimestampService().getNonce());
        request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey());
        request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod());
        request.addOAuthParameter(OAuthConstants.VERSION, getVersion());
        request.addOAuthParameter(OAuthConstants.SCOPE, config.getScope());
        request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, token));

    }

    private String getSignature(OAuthRequest request, Token token) {

        String baseString = api.getBaseStringExtractor().extract(request);
        String signature = api.getSignatureService().getSignature(baseString, config.getApiSecret(), token.getSecret());

        return signature;
    }

    private void appendSignature(OAuthRequest request) {
        for (Map.Entry<String, String> entry : request.getOauthParameters().entrySet()) {
            request.addQuerystringParameter(entry.getKey(), entry.getValue());
        }
    }

    @Override
    public Token getRequestToken(RequestTuner tuner) {
        OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint());

        addOAuthParams(request, OAuthConstants.EMPTY_TOKEN);
        appendSignature(request);

        Response response = request.send(tuner);
        String body = response.getBody();

        return api.getRequestTokenExtractor().extract(body);
    }
}

TrakingApi будет немного отличаться для создания OAuth10aServiceForViagogo при вызове createService :

import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.Token;

public class TradeKingAPI extends DefaultApi10a {

    @override
    public OAuthService createService(OAuthConfig config)
    {
      return new OAuth10aServiceForViagogo(this, config);
    }

    @Override
    public Verb getRequestTokenVerb()
    {
      return Verb.GET;
    }

    @Override
    public String getRequestTokenEndpoint() {
        return "http://api.viagogo.net/Public/SimpleOAuthAccessRequest";
    }

    @Override
    public String getAccessTokenEndpoint() {
        return "none";
    }

    @Override
    public String getAuthorizationUrl(Token requestToken) {
        return "none";
    }
}

Тогда ваш код вызова будет таким же:

    OAuthService service = new ServiceBuilder()
                                .provider(TradeKingAPI.class)
                                .signatureType(QueryString)
                                .apiKey("My consumer key")
                                .apiSecret("My secret")
                                .scope("API.Public")
                                .build();

    Token requestToken = service.getRequestToken();

    //make your API calls

    OAuthRequest request = new OAuthRequest(Verb.GET,
                           "http://api.viagogo.net/Public/Event/235");
    service.signRequest(requestToken, request);
    Response response = request.send();
    System.out.println(response.getBody());

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

person Antoine Sabot-Durand    schedule 22.07.2013
comment
Я использовал оба метода, но столкнулся с теми же ошибками, мне также интересно, где вы извлекаете эти переменные, такие как config.getApiKey() - person ; 25.07.2013
comment
Как я уже сказал, без потребительского ключа вам очень трудно помочь, потому что это похоже на тестирование в темноте: у каждой социальной сети есть свои маленькие хитрости, которые вы можете увидеть только при реальном тестировании. Если у вас есть способ достать мне ключ, я могу попробовать... - person Antoine Sabot-Durand; 25.07.2013
comment
config является объектом OauthConfig. Это внутренний класс, используемый Scribe ServiceBuilder, он создается при вызове build(): bit.ly/166IUnq - person Antoine Sabot-Durand; 25.07.2013
comment
Я заметил, что, когда я использовал ваш код, я пропустил .signatureType(QueryString), когда добавлял его, IDE показывает ошибку, которую он не распознает. - person ; 26.07.2013
comment
Это перечисление: org.scribe.model.SignatureType.QueryString попробуйте заменить SignatureType на SignatureType.QueryString ваша IDE должна его найти. - person Antoine Sabot-Durand; 26.07.2013
comment
Хм @ J888, возможно, вы могли бы оставить отзыв о моем ответе на ваш вопрос. Примите это или присудите награду до окончания льготного периода или скажите, что с этим не так. Спасибо - person Antoine Sabot-Durand; 28.07.2013
comment
Извините за задержку, я все еще изучаю проблему - person J888; 29.07.2013
comment
@AntoineSabot-Durand Я тоже пробовал код, но он не работает. Я использовал System.out.println(request.send().isSuccessful()); который возвращает ложь - person ; 29.07.2013
comment
@MirMoorido Опять же, я не могу помочь без ключа приложения для Viagogo для выполнения тестов. Поскольку они не отвечают, когда вы обращаетесь в их службу поддержки (спрашивайте на прошлой неделе), единственным решением, если вам нужна дополнительная помощь, будет отправить мне ключ вашего приложения по почте: asd [at] redhat [dot] com. - person Antoine Sabot-Durand; 29.07.2013
comment
@AntoineSabot-Durand Я пытаюсь выполнить аналогичную аутентификацию с помощью Netsuite API, но нам предоставляется только «URL-адрес авторизации», а не «RequestTokenEndpoint». Мне интересно, является ли RequestTokenEndpoint обязательным или мы можем аутентифицироваться только с помощью «AuthorizationURL»? - person RanPaul; 21.01.2019

Я предполагаю, что вы пытаетесь получить токен доступа (например, вы вызываете SimpleOAuthAccessRequest). OauthService Scribe имеет методы для решения этой проблемы.

НО... если вы собираетесь делать это вручную, вот что не так с вашим кодом - по крайней мере, с тем, что вы здесь перечислили. Я предполагаю, что вы правильно настроили писец.

  • не передавайте секрет потребителя с вашим запросом, это только для подписи запроса
  • вы должны использовать addOauthParameter против addQueryStringParameter
  • вы должны использовать константы Scribe
  • вам нужно подписать запрос (опять же, OauthService Scribe имеет метод помощи для подписания запроса)

Вот ваш обновленный фрагмент кода.

ОБНОВЛЕНИЕ: попросите Scribe предоставить вам все параметры Oauth

OAuthRequest request = new OAuthRequest(Verb.GET, ...
//since you're just passing Oauth parameters and nothing else, 
//you can use signRequest will create Oauth Parameters for you
service.signRequest(OAuthConstants.EMPTY_TOKEN, request)
Response response = request.send()
person ikumen    schedule 18.07.2013
comment
Спасибо за ваш ответ, на самом деле я предпочитаю делать это автоматически, но не смог найти учебник, чтобы изучить его. Что касается конфигурации писца, я обновлю код. - person J888; 19.07.2013
comment
не уверен, видели ли вы, но писец страница git содержит примеры того, как использовать OauthService для получения токена доступа: - person ikumen; 19.07.2013
comment
да, я пытался использовать разные части этих кодов для его сборки :D - person J888; 19.07.2013
comment
Спасибо за ваш ответ, он показывает сообщение об ошибке в строке oauthService.signRequest, вопрос обновлен. - person J888; 21.07.2013
comment
Извините, я взглянул на код, который я вам дал, и понял, что он совершенно неверен (я перепутал то, что у меня есть в моем проекте, с тем, что вы делаете). По сути, поскольку вы просто отправляете запрос на конечную точку только с параметрами Oauth, вы можете создать Scribe и подписать параметры Oauth с помощью метода signRequest. Ранее я перепутал signRequest с тем, что должно было быть getSignature - person ikumen; 21.07.2013