Search code examples
javagrailsoauthyahoo-apisignpost

Refresh Yahoo Oauth Access Token using grails-oauth plugin based on sign-post api


I am using grails oauth plugin. Which is providing me yahoo's access_token successfully. But the problem is -- this token (from yahoo) has validity of 1 hr only. And after that we need to refresh it. And going through their documentation it seems like they have process to refresh it (in case token expires). And this call bypasses the thrid leg (user's manual acceptance process). that's very good!

Now, if I am trying to use method oauthService.fetchAccessToken -- I guess this is the method which hits get_access_token url (at provider's side). But I am getting exception:

oauth.signpost.exception.OAuthNotAuthorizedException: Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match. at oauth.signpost.AbstractOAuthProvider.handleUnexpectedResponse(AbstractOAuthProvider.java:239) at oauth.signpost.AbstractOAuthProvider.retrieveToken(AbstractOAuthProvider.java:189) at oauth.signpost.AbstractOAuthProvider.retrieveAccessToken(AbstractOAuthProvider.java:99) at oauth.signpost.OAuthProvider$retrieveAccessToken.call(Unknown Source) at org.grails.plugins.oauth.OauthService.fetchAccessToken(OauthService.groovy:286) at org.grails.plugins.oauth.OauthService$fetchAccessToken.call(Unknown Source)


I have debugged further into plugin and signpost code. And I think we should look into signpost (for now), plugin can be modified easily later.

For your information, I am using signpost (jar - 1.2.1.1) with commonshttp4 client

here's the link of Yahoo documentation page for refreshing the accessToken. http://developer.yahoo.com/oauth/guide/oauth-refreshaccesstoken.html

Yahoo needs oauth_session_handle parameter in the request which is sent by yahoo with accessToken. Signpost does provides a way to fetch this -- provider.getResponseParameters().

Now next is, I am using following way to put these parameters back into the refreshToken request -- consumer.setAdditionalParameters(httpParams)

But it doesn't work! Following is the part of stacktrace. When I try to get the refreshedAccessToken

oauth.signpost.exception.OAuthNotAuthorizedException: Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match. at oauth.signpost.AbstractOAuthProvider.handleUnexpectedResponse(AbstractOAuthProvider.java:239) at oauth.signpost.AbstractOAuthProvider.retrieveToken(AbstractOAuthProvider.java:189) at oauth.signpost.AbstractOAuthProvider.retrieveAccessToken(AbstractOAuthProvider.java:99)

looking forward to hear soon from some great/generous guy(s) :-)

Thanks, Salil


Solution

  • I have found the answer and want to share it others (who might trap with similar situation).

    First of all, if you are using signpost library for oauth, I would recommend you to stop using it. Because, the development has been stopped since jan 2011. Read this: http://brainflush.wordpress.com/2011/01/27/stepping-back-from-signpost-development/

    I used 'scribe-java' for this. here's the link on github. You can either use maven or download jar or just fork the code. https://github.com/fernandezpablo85/scribe-java/

    It's very easy to use, even the (top) service providers URLs are configured beforehand.

    here's the code how to refresh it using scribe-java library.

    Token accessToken = new Token('your-expired-token-key', 'your-expired-token-secret')
    println ".......................... Expired Token ........................\n $accessToken"
    
    OAuthRequest request = new OAuthRequest(Verb.GET, "https://api.login.yahoo.com/oauth/v2/get_token");
    request.addOAuthParameter('oauth_session_handle', 'your-yahoo-session-handle') // you need to fetch it from the parameters when get your access token.
    service.signRequest(accessToken, request);
    Response response = request.send();
    accessToken = YahooApi.class.newInstance().getAccessTokenExtractor().extract(response.getBody())
    
    println ".......................... Refreshed Token ........................\n $accessToken"