9

I need to make a connection with Viagogo website using oAuth. Referring to their documentation I need to create a request similar to the following one

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

I am using the following code but when I comment lines 1,2 it return unauthorized error, and when I use them it shows oauthService.signRequest returns 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());
6
  • 2
    have you searched around and maybe found Similar questions Commented Jul 18, 2013 at 14:11
  • 2
    Why not use existing Java OAuth libraries? Commented Jul 18, 2013 at 14:14
  • @BuhakeSindi I could not find any, would you give me an example ? or point me to a tutorial please thanks. Commented Jul 18, 2013 at 23:01
  • @Mgetz have tcame across that one before, but prefer to do it automatically that answer requires many lines of codes. Commented Jul 18, 2013 at 23:03
  • @JackRamzi, there are few, like Scribe or JOAuth, to name a few. Commented Jul 19, 2013 at 9:31

2 Answers 2

9
+75

From what I understand from Viagogo public API access documentation, the token you get in the step 1, is the equivalent to a request token in a complete OAuth 1.0a "dance".

So, you should be able to use scribe-java internal classes to get this token without doing it by hand. The only difference is that in scribe, this request sends also a callback url to the OAuth server for the next step of OAuth "dance".

As I can't get a consumer account I can only make assumption here. So let's have 2 scenarios :

Scenario 1 : Viagogo server tolerate extra parameter (i.e. call back URL)

so you can go with this code

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";
    }
}

Then your calling code will be :

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());

But as I said, if Viagogo security is a bit strict and it refuses the useless param oauth_callback, you'll need to switch to scenario 2

Scenario 2 : Build your own OAuthService

In this scenario you have to create a new OAuthService to avoid dealing with OAuthCallback parameter.

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 class will be slightly different to create the an OAuth10aServiceForViagogo when calling 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";
    }
}

Then your calling code will be the same :

    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());

I didn't test all this code because I can't access consumer and secret key, but it should be close to what you need.

Sign up to request clarification or add additional context in comments.

10 Comments

I used both methods but run into same errors, I am also wondering where you are retrieving those variables such as config.getApiKey()
As I said without a consumer key it's very hard to help you, because it's like testing in the dark : each Social media has it's little twist you can only see when testing for real. If you have a way to obtain me a key, I can give a try...
config is an OauthConfig object. It is an internal class used by Scribe ServiceBuilder, it is instantiated when you call build(): bit.ly/166IUnq
I have noticed while I was using your code, I missed the .signatureType(QueryString) when I added it the IDE shows an error that it does not recognise it
It's an enum: org.scribe.model.SignatureType.QueryString try to replace SignatureType by SignatureType.QueryString your IDE should find it.
|
3

I'm assuming you're trying to get the access token (e.g you're calling SimpleOAuthAccessRequest). Scribe's OauthService has methods to handle this.

BUT ... if you're going to do it manually, here is what's wrong with your code - at least with what you've listed here. I'm assuming you've configured scribe correctly.

  • don't pass the consumer secret with your request, that is only for signing the request
  • you should use addOauthParameter vs addQueryStringParameter
  • you should use the Scribe constants
  • you need to sign the request (again, Scribe's OauthService has help method for signing request)

Here's your updated snippet of code.

UPDATE: Have Scribe provide all the Oauth parameters for you

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()

5 Comments

Thanks for your answer, actually I prefer to do it automatically but could not find a tutorial to learn it. Regarding scribe configuration I will update the code.
not sure if you've seen, but the scribe git page has examples on how to use the OauthService to retrieve the access token:
yes I tried to use different parts of those codes to assemble it :D
Thanks for your answer, It shows an error message on oauthService.signRequest line, question is updated.
Sorry, I took a look at the code I gave you and realize it was totally wrong (I mixed up what I have on my project with what you're doing). Basically since you're just sending a request to the endpoint with only Oauth parameters you can have Scribe create and sign the Oauth parameters w/ signRequest method. Earlier I mixed up the signRequest with what should have been getSignature

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.