9

我需要使用 oAuth 与Viagogo 网站建立连接。参考他们的文档,我需要创建一个类似于以下的请求

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 行时,它返回未经授权的错误,当我使用它们时,它显示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());
4

2 回答 2

10

根据我从 Viagogo 公共 API 访问文档中了解到的情况,您在步骤 1 中获得的令牌等同于完整的 OAuth 1.0a“舞蹈”中的请求令牌。

因此,您应该能够使用 scribe-java 内部类来获取此令牌,而无需手动操作。唯一不同的是,在 scribe 中,此请求还会向 OAuth 服务器发送一个回调 url,用于 OAuth 的下一步“跳舞”。

由于我无法获得消费者帐户,我只能在这里做出假设。所以让我们有两个场景:

场景一: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);
    }
}

TrakingApiOAuth10aServiceForViagogo调用时创建的类会略有不同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());

我没有测试所有这些代码,因为我无法访问消费者和密钥,但它应该接近你需要的。

于 2013-07-22T15:31:58.413 回答
3

我假设您正在尝试获取访问令牌(例如,您正在调用 SimpleOAuthAccessRequest)。Scribe 的 OauthService 具有处理此问题的方法。

但是......如果您要手动执行此操作,那么您的代码有什么问题 - 至少您在此处列出的内容是这样。我假设你已经正确配置了 scribe。

  • 不要在您的请求中传递消费者秘密,这仅用于签署请求
  • 你应该使用 addOauthParameter vs addQueryStringParameter
  • 您应该使用 Scribe 常量
  • 您需要签署请求(同样,Scribe 的 OauthService 有用于签署请求的帮助方法)

这是您更新的代码片段。

更新: 让 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()
于 2013-07-18T17:35:04.710 回答