0

I am trying to getting access to Khan Academy using ScribeJava OAuth mechanism. After getting a token successfully I get an exception of 401. Which is quite definite about unauthorized access. And If I change the URL to the one

http://api-explorer.khanacademy.org/api/v1/user/videos/cGg1j1ZCCOs?userId=vilething&username=&email=

It gives me a response. But, all the user related information is empty in response.

public abstract class KhanAcademyAccess {

    private final static String USER_AGENT = "Mozilla/5.0";

    public static void main(String... args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, IOException, Exception {
        String videoId = "C38B33ZywWs";
        String username = "###";
        String password = "###";
        final OAuth10aService service = new ServiceBuilder()
                .apiKey("###")
                .apiSecret("###")
                .build(KAApi.instance());

        //Get Request Token
        final OAuth1RequestToken requestToken = service.getRequestToken();

        System.out.println(requestToken.getToken());
        sendPost("https://www.khanacademy.org/api/auth2/authorize", username, password, requestToken.getToken().toString());
        final OAuth1AccessToken accessToken = service.getAccessToken(requestToken, "");
        System.out.println(accessToken);


        final OAuthRequest request = new OAuthRequest(Verb.GET, "https://www.khanacademy.org/api/internal/_mt/user/videos/cGg1j1ZCCOs/log_compatability?", service);

        service.signRequest(accessToken, request);
          request.addHeader("Accept", "application/json; charset=utf-8");
            request.addHeader("Content-Type", "application/json; charset=utf-8");
            request.addHeader("X-Requested-With", "XMLHttpRequest");
            request.addHeader("Accept-Encoding", "application/json");

         Response response = request.send();

        System.out.println(response.getCode());
        System.out.println(response.getMessage());
        System.out.println(response.getBody());
    }
private static void sendPost(String url, String username, String password, String oauthToken) throws Exception {

        DefaultHttpClient httpclient = new DefaultHttpClient();
        // Comment out from here (Using /* and */)...
        // ...to here and the request will fail with "HttpResponseException: Moved Permanently"
        try {
            HttpPost httpPost = new HttpPost(url);
            String encoding = Base64Encoder.getInstance().encode(StringUtils.getBytes(username + ":" + password));

            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("identifier", username));
            params.add(new BasicNameValuePair("password", password));
            params.add(new BasicNameValuePair("oauth_token", oauthToken));

            httpPost.setEntity(new UrlEncodedFormEntity(params));
            System.out.println("executing request " + httpPost.getURI());
            // Create a response handler
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            HttpResponse responseBody = httpclient.execute(httpPost);
            // Add your code here...
            int responseCode = responseBody.getStatusLine().getStatusCode();
            while(responseCode!=200 ){
                for(Header header : responseBody.getAllHeaders()){
                    if(header.getName().equalsIgnoreCase("Location")){
                        responseCode = getRequest(header.getValue());
                    }

                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // When HttpClient instance is no longer needed, shut down the connection 
            // manager to ensure immediate deallocation of all system resources
        }

    }

I am using username and password authentication because I want to automate the authorization process and don't want user to be redirected to the page and click on Accept button.

Adding logs that may be useful in order to identify the problem

Request Token:

OAuth1RequestToken{oauth_token=t0000005405940108, oauth_token_secret=NyGQchdSAj7AwukA, oauth_callback_confirmed=true}

Access Token:

OAuth1AccessToken{oauth_token=t0000005413417574, oauth_token_secret=UMAV7Y54suAVPcJZ}

Wasif Kirmani
  • 1,277
  • 3
  • 22
  • 43

1 Answers1

0

The purpose of OAuth is to avoid your application needing to know a user's username and password. With Oauth1, the browser redirect is standard procedure. Many of your users may also be using Google and Facebook to login, so you won't be able to use their credentials directly.

For an example of how to use the Khan API with java, see this example gist

thomas88wp
  • 2,381
  • 19
  • 31