I am new to OAuth and I'm developing an Android app that requires it and I'm using the signpost library.
I believe I have it all working up to the point where I can get the token using
String token = uri.getQueryParameter("oauth_token");
Which returns correctly however the very next line
String verifier = uri.getQueryParameter("oauth_verifier");
returns null. I have debugged and inspected uri which is initialized as
Uri uri = this.getIntent().getData();
And it does not appear to have a key "oauth_verifier"
The verifier being null causes an OAuthExpectationFailedException when I try the ofllowing line
provider.retrieveAccessToken(consumer, verifier);
Can anyone help me figure out why the verifier is null I am using a callback not OOB.
I have seen in other questions and guides the likes of this in the response:
dat=myapp://twitter?oauth_token=tJpJHOOwoTGMwdvHyYbfX2tyHKOp0Y2kdRRZf3sM&
oauth_verifier=xc49oM8eVVmK46ZSLz2RMT2uqXn3SxrMxf5ZAMXaD2Y
Mine is similar but without the ouath_verifier key.
Here is where I send the initial intent which works and I get a return
String clientKey = "xxxxxxx";
String clientSecret = "yyyyyyyyy";
CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(clientKey,clientSecret);
provider = new CommonsHttpOAuthProvider(URL_Request_Token,
URL_Access_Token,
URL_Authorize";
provider.setOAuth10a(true);
try {
String authUrl = provider.retrieveRequestToken(consumer,CALLBACK_URI.toString());
String token = consumer.getToken();
String secret = consumer.getTokenSecret();
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
}
Any help is much appreciated
A problem I had while developing a twitter interaction sample is that I forgot to set a callback url from the twitter app console.
If you don't do that, your application won't be redirected and so it won't be able to grap the verifier token.
PROMO MODE ON
However, if you feel particularly brave, I've been working on this library PostManLib lately and I am looking for beta testers. It should handle all the async oauth interaction using the well know scribe library under the hood.
PROMO MODE OFF
Related
I am trying to use a URL shortener, with Scribe, based on this example.
However, I want to make sure I can track the visits which my short URL gets, which means it must be unique. To create unique links, I need to authenticate with Google, as per this.
Signed in
Your links are automatically added to goo.gl where you can track their use.
A unique short URL is created each time a long URL is shortened.
Signed out
Your links won’t show up on your goo.gl page.
The same short URL is reused each time a long URL is shortened by you or someone else.
In the example, the oAthRequest is not signed with the oAuthService. I have updated this so that it can sign the request and send it (as a signed in user).
Here is my code:
private static final String API_KEY = "XXXXXXXX";
private static final String API_URL = "https://www.googleapis.com/urlshortener/v1/url";
private static final String API_URL_WITH_KEY = API_URL + "?key=" + API_KEY;
public TrackableLink createTrackableLink(String longUrl) {
OAuthService oAuthService = new ServiceBuilder()
//Google Api Provider - Google's URL Shortener API is part of Google Platform APIs
.provider(GoogleApi.class)
/*
Using "anonymous" as API Key & Secret because Google's URL Shortener service
does not necessarily requires App identification and/or User Information Access
*/
.apiKey("anonymous")
.apiSecret("anyonymous")
//OAuth 2.0 scope for the Google URL Shortener API
.scope("https://www.googleapis.com/auth/urlshortener")
//build it!
.build();
Token requestToken = oAuthService.getRequestToken();
OAuthRequest request = new OAuthRequest(Verb.POST, API_URL_WITH_KEY);
request.addHeader("Content-Type", "application/json");
request.addPayload(new JSONObject().put(RESPONSE_LONG_URL, longUrl)
.toString());
oAuthService.signRequest(requestToken, request);
Response response = request.send();
JSONObject json = new JSONObject(response.getBody());
String shortUrl = json.getString(RESPONSE_SHORT_URL);
TrackableLink tl = new TrackableLink(longUrl, shortUrl);
return tl;
}
I replace the "anonymous" details with my values from the Google API website, and I get this exception:
Can't extract token and secret from this: 'Consumer is not registered: 7629638329XXXXXXXXXXX.apps.googleusercontent.com
I'm not sure exactly what I am doing wrong here. I have tried almost every combination of values for the key/secret from the various keys the google console gives me, could this be caused by something else other than something up with the API key?
Any ideas why I am getting the consumer is not registered error? On my Google account, I have enabled the API.
I am trying to build authentication flow in our app for facebook in java. I am using facebook4j library.
My corresponding code is as follows -
public String authenticate() throws IOException {
Facebook facebook = new FacebookFactory().getInstance();
String redirectURL = facebook.getOAuthAuthorizationURL("http://localhost:9099/default/facebook/verify.html");
servletResponse.sendRedirect(redirectURL);
return null;
}
public String verify() throws Exception {
String code = servletRequest.getParameter("code");
Facebook facebook = new FacebookFactory().getInstance();
AccessToken accessToken = facebook.getOAuthAccessToken(code);
String token = accessToken.getToken();
servletResponse.getWriter().write(token);
return null;
}
I am getting error after redirection on this line -
AccessToken accessToken = facebook.getOAuthAccessToken(code);
The error is as follows -
FacebookException{statusCode=400, errorType='OAuthException', errorMessage='redirect_uri isn't an absolute URI. Check RFC 3986.', errorCode=191, errorSubcode=-1, version=2.2.2}
at facebook4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:179)
at facebook4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:65)
at facebook4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:97)
at facebook4j.auth.OAuthAuthorization.getOAuthAccessToken(OAuthAuthorization.java:107)
redirectURL that I am getting from facebook in first call is -
https://www.facebook.com/dialog/oauth?client_id=4161XXXXXX6389&redirect_uri=http%3A%2F%2Flocalhost%3A9099%2Fdefault%2Ffacebook%2Fverify.html&scope=email,public_profile,user_friends
tried without using encoding too -
https://www.facebook.com/dialog/oauth?client_id=4161XXXXXX6389&redirect_uri=http://localhost:9099/default/facebook/verify.html&scope=email,public_profile,user_friends
It is redirecting properly to 'verify' having url something like -
http://localhost:9099/default/facebook/verify.html?code=AQCE4aaIpE_c94J3NVNjge_YL_OP84vPIgUauvfRRXNCj_FOK8U2kfSxfKGrjWnFL1dqMeM8q22M6UaVbGsTpTQOQmjxYILdFHKFiSFd0Ycf_ByBE9rNX_yxvFnJ3RNLf7bjCT4C1uXuuqCXHZjVNN1lBb3LWUHz7eNkq0r8K14x7ZEVIWjbll-Vqys1FZuCIVDBrI4StoYkZR1rpCsoSqq7VdCIX3zawnw_nbPZBZU7iUeZJiBbahYjWkHIn47b9AQb3hZxxpe4xxXHXfDsP_h2fhC1YYioJbwGq4QbnWpUrP7aF-0Q_wF71zn4txCQLd4#=
facebook4j.properties
oauth.appId=416XXXXXXXXX389
oauth.appSecret=9ed3XXXXXXb6acXXXXXXXXc7acXXXX5
oauth.permissions=email,public_profile,user_friends
My Facebook App basic settings are -
The important advanced settings are -
I am totally aware that similar question has been posted earlier multiple times. I have gone through almost every question & I tried almost everything suggested to resolve this issue. But due to some reason it is not working. I decided to post my problem here after spending 3 days on the same issue.
I would highly appreciate if someone points out where exactly am I going wrong.
The redirect_uri parameter has to be specified when exchanging the code for a token as well (and has to be the same as specified earlier in the login dialog call).
I’d assume that since you are using new FacebookFactory().getInstance() in your second method, that is not the case. Take a look at the basic implementation here, https://github.com/roundrop/facebook4j-oauth-example/tree/master/src/main/java/facebook4j/examples/signin
In SignInServlet, the Facebook object instance is stored into the session, and then in CallbackServlet that same instance is retrieved and used again. Therefor, it still holds the redirect_uri value that was initially used when the Auth dialog was called, and will re-use that same value when exchanging the code for a token.
Im trying to update twitter status using java with Scribe library (1.3).
Asking for a proctected resource as in the example works fine. (https://github.com/fernandezpablo85/scribe-java/blob/master/src/test/java/org/scribe/examples/TwitterExample.java)
However, I get the next error when im trying to write a tweet:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot get String from a null object
at org.scribe.utils.Preconditions.check(Preconditions.java:80)
at org.scribe.utils.Preconditions.checkNotNull(Preconditions.java:27)
at org.scribe.utils.StreamUtils.getStreamContents(StreamUtils.java:20)
at org.scribe.model.Response.parseBodyContents(Response.java:41)
at org.scribe.model.Response.getBody(Response.java:67)
at model.TwitterExample.main(TwitterExample.java:84)
Highlight code parts:
OAuthService service = new ServiceBuilder()
.provider(TwitterApi.Authenticate.class)
.apiKey("------------------------------")
.apiSecret("--------------------------------")
.build();
Scanner in = new Scanner(System.in);
// Obtain the Request Token
Token requestToken = service.getRequestToken();
Verifier verifier = new Verifier(in.nextLine());
// Trade the Request Token and Verfier for the Access Token
Token accessToken = service.getAccessToken(requestToken, verifier);</java>
String tweet = URLEncoder.encode("First Tweet","UTF-8");
String urlTweet="http://api.twitter.com/1.1/statuses/update.json?status="+tweet;
System.out.println("request: "+urlTweet);
OAuthRequest request2 = new OAuthRequest(Verb.POST, urlTweet);
service.signRequest(accessToken, request2);
System.out.println("REQUEST: " + request2.getUrl());
Response response2 = request2.send();
System.out.println(response2.getBody());
This exception throws in "response2.getBody()" print.
I have not been able to find the right solution to my problem in your discussions and external forums, so any help is appreciated.
Thank you in advance!
Try checking response2.getCode() before response2.getBody(), maybe you're getting an error (such a 403 - forbidden) and you're ignoring it.
Hope it helps.
Ok, I got it.
I noticed that the way requests works on twitter have changed just a month ago, and now it has to be used https instead of http.
I did some adjustments in my code before this question in reference to this, like using
.provider(TwitterApi.Authenticate.class)
instead of
.provider(TwitterApi.class).
Even so, I did not change this sentence of my code, which was the reason of my error.
String urlTweet="http://api.twitter.com/1.1/statuses/update.json?status="+tweet;
to
String urlTweet="https://api.twitter.com/1.1/statuses/update.json?status="+tweet;
I hope that if someone comes here with same problem can solve it with this relevant info.
https://github.com/leleuj/pac4j/issues/24
https://github.com/juliendangers/pac4j/commit/72d025e219dd11f854ecf1f8156e48f688d55615
Thanks eltabo for taking me to the right direction.
I want to build an app in Java based on live showing certain photos of Instagram tagged with a particular hashtag. I'm currently trying to use jInstagram, but I can't understand the flow of the API Instagram. It's not like the Twitter API. Instagram API seems to call for a server in the middle of my app and their servers, while Twitter API gave me access to the gardenhose without a lot of work. And, overall, thanks to the nice samples on Twitter4J.org
I'd be grateful if somebody can help me to start with. I just want to get live photos with certain hashtag of Instagram but I don't know if I'd should set up a server or where they give me an access token.
First you need to register your app to instagram's website and get your apiKey and apiSecret. Then you can choose a callback URL and a scope.
InstagramService service = new InstagramAuthService()
.apiKey("e607b7XXXce54e729bXXXXf40162")
.apiSecret("651cXXX2ab348a3XXXXa7ae90c6d")
.callback("http://www.cagdasalagoz.com")
.scope("basic public_content likes comments follower_list relationships")
.build();
After this, you can get the authorization like this.
String authorizationUrl = service.getAuthorizationUrl();
System.out.println(authorizationUrl); //paste in browser
Scanner sc = new Scanner(System.in);
System.out.println("Paste the code gotten in the browser (at the end of the URL): ");
String verCode = sc.nextLine(); //SCAN VERIFIER CODE
Verifier verifier = new Verifier(verCode);
Token accessToken = service.getAccessToken(verifier); //Token successfully gotten
//** RUNS OK UP TO THIS LINE INCLUDED **//
Instagram instagram = new Instagram(accessToken); //Ok
About getting the posts by a tag can be achived by this method I guess.
String tag="seaside";
instagram.getRecentMediaFeedTags(tag);
You can learn more about jInstagram from this page.
I am writing a web application and have just implemented that a user can sign in via Twitter, using spring-social-(core/twitter).
However, Twitter behaves strangely. After the initial authentication/authorization, every time I'm sending a user to Twitter for authentication, Twitter prompts to authorize my application again. I've looked into the connected Twitter profile. My app is there and authorized correctly (in my case for read access).
I don't have a case of requesting additional permissions. All my application needs is read access (the authorization dialog confirms this).
I am using the OAuth1Operations (returned by the TwitterConnectionFactory) to do the OAuth dance and save the resulting connection in a database. My front-end is written with Wicket 1.5.
I can work around this behavior by just re-authorizing my app again and again when I want to sign in via Twitter, but this is a big nuisance. Anyone knows what I'm missing here?
Here is my code:
TwitterConnectionFactory connectionFactory = (TwitterConnectionFactory) connectionFactoryLocator.getConnectionFactory(Twitter.class);
String callbackUrl = [...];
if (pageParameters.get("oauth_token").isNull() || pageParameters.get("oauth_verifier").isNull()) {
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("x_auth_access_type", "read");
OAuthToken token = connectionFactory.getOAuthOperations().fetchRequestToken(callbackUrl, params);
String url = connectionFactory.getOAuthOperations().buildAuthorizeUrl(token.getValue(), OAuth1Parameters.NONE);
getSession().setAttribute("twitter_token", token);
setResponsePage(new RedirectPage(url));
} else {
String token = pageParameters.get("oauth_token").toString();
String verifier = pageParameters.get("oauth_verifier").toString();
OAuthToken previousToken = (OAuthToken) getSession().getAttribute("twitter_token");
if (previousToken.getValue().equals(token)) {
AuthorizedRequestToken authorizedRequestToken = new AuthorizedRequestToken(previousToken, verifier);
OAuthToken accessToken = connectionFactory.getOAuthOperations().exchangeForAccessToken(authorizedRequestToken, null);
Connection<Twitter> connection = connectionFactory.createConnection(accessToken);
}
}
I've found the solution! It is also detailed here: Simple Twitter Oauth authorization asking for credentials every time
The problem was that I specifically requested Twitter to authorize my app every time. Replacing:
String url = connectionFactory.getOAuthOperations().buildAuthorizeUrl(token.getValue(), OAuth1Parameters.NONE);
with
String url = connectionFactory.getOAuthOperations().buildAuthenticateUrl(token.getValue(), OAuth1Parameters.NONE);
solves the issue!
Calling the URL for authentication does only ask for authorization if the app hasn't been authorized yet.