Question

Can anyone help me understand OAuth flow for Khan Academy API. It can be accessed through this link: https://github.com/Khan/khan-api/wiki/Khan-Academy-API-Authentication

I am using Scribe.

Here is the working code:

     OAuthService serv = new ServiceBuilder().provider(KhanApi.class)
     .apiKey("").apiSecret("")
     .build();
     Token token = new Token("", "");

     OAuthRequest req = new OAuthRequest(Verb.GET,
     "http://www.khanacademy.org/api/auth/request_token");

     serv.signRequest(token, req);

     Response resp = req.send();
     System.out.println(resp.getBody());

After you get the response you need to redirect user to that page. Then after a successful login browser will respond with a url which contains request token...

Here are two different things that I tried and didn't work out well and their results:

1)

 OAuthService serv = new ServiceBuilder().provider(KhanApi.class)
 .apiKey("***").apiSecret("***")
 .build();
 Token token = serv.getRequestToken();

the result is :

Exception in thread "main" org.scribe.exceptions.OAuthException: Response body is incorrect. Can't extract token and secret from this:

<!DOCTYPE html>
<html>
    <head>
        <title>Login to Khan Academy</title>

        <style>
            #login-page {
                padding-top: 18px;
            }
            .providers {
                height: 100px;
            }
            .providers .provider .img-container {
                height: 80px;
            }

           .horizontal-separator .separator-text {
                background-color: white;
                margin-left: 185px;
            }
            .pw-login {
                width: 415px;
                height: auto;
                text-align: right;
            }
            .pw-login img.tree {
                float: left;
            }

        </style>


    </head>
    <body>
        <article id="login-page">
            <div id="login-inner-content">
                <form method="POST"
                    class="auth-form"
                    id="login-form"
                    action="https://khan-academy.appspot.com/login/mobileoauth">
                <h3>Login to Khan Academy</h3>
                <input type="hidden" name="oauth_map_id" value="889298340">
                <input type="hidden" name="view" value="normal">


                <ul class="providers">
                    <li class="provider action-gradient" title="Google">

            </div>
        </article>
    </body>
</html>'
    at org.scribe.extractors.TokenExtractorImpl.extract(TokenExtractorImpl.java:41)
    at org.scribe.extractors.TokenExtractorImpl.extract(TokenExtractorImpl.java:27)
    at org.scribe.oauth.OAuth10aServiceImpl.getRequestToken(OAuth10aServiceImpl.java:52)
    at com.saeid.scribe.oauth.Main.main(Main.java:117)

The response is a string of a broken html file.(broken in the sense that images are not being shown...)

2) Also I tried:

    OAuthRequest req = new OAuthRequest(Verb.GET,
            "http://www.khanacademy.org/api/auth/request_token");

    Map<String, String> parameters = generateParameters("GET",
            "http://www.khanacademy.org/api/auth/request_token");

    req.addQuerystringParameter("oauth_consumer_key", parameters.get("oauth_consumer_key"));
    req.addQuerystringParameter("oauth_nonce", parameters.get("oauth_nonce"));
    req.addQuerystringParameter("oauth_signature", parameters.get("oauth_signature"));
    req.addQuerystringParameter("oauth_signature_method", parameters.get("oauth_signature_method"));
    req.addQuerystringParameter("oauth_timestamp", parameters.get("oauth_timestamp"));
    req.addQuerystringParameter("oauth_version", parameters.get("oauth_version"));

    Response res = req.send();

the result is:

OAuth error. Invalid signature. Expected signature base string: GET&http%3A%2F%2Fwww.khanacademy.org%2Fapi%2Fauth%2Frequest_token&oauth_consumer_key%3D***********%26oauth_nonce%3D1341526030%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1341526030%26oauth_version%3D1.0

I am using the same base string to generate signature and I am using consumer key as the key for HMAC-SHA1 method.

Here is the how KhanAPI looks like: import org.scribe.builder.api.DefaultApi10a; import org.scribe.model.Token;

public class KhanApi extends DefaultApi10a{

@Override
public String getAccessTokenEndpoint() {
    return "http://www.khanacademy.org/api/auth/access_token";
}

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

@Override
public String getRequestTokenEndpoint() {
    return "http://www.khanacademy.org/api/auth/request_token";
}

}

Can anyone help me? Thanks,

Was it helpful?

Solution

doesn't Scribe add all of the required OAuth parameters, and perform the signing for you? i'm looking at the LinkedIn example, which is based off of a default OAuth 1.0a flow, and i don't see it doing anything like that.

https://github.com/fernandezpablo85/scribe-java/blob/master/src/test/java/org/scribe/examples/LinkedInExample.java

if you have to manually formulate the URL and sign it yourself, what exactly is Scribe doing for you?

OTHER TIPS

This api returns an expected base string, which is great. You can run scribe in debug mode and see what base string you're generating, like this:

 OAuthService serv = new ServiceBuilder().provider(KhanApi.class)
 .apiKey("***").apiSecret("***")
 .debug()
 .build();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top