Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I am unable to use Reddit's APIs to log in

Tags:

java

reddit

I'm trying to use the Reddit API to do some stuff. I have everything working but changing pages and logging in.

I need to login to use my program, I know how to use the cookie I get, but I just can't manage to login.

Here's the code:

public static Login POST(URL url, String user, String pw) throws IOException
{

    String encodedData =  URLEncoder.encode("api_type=json&user=" + user +"&passwd="+pw, "UTF-8");
    HttpURLConnection ycConnection = null;
    ycConnection = (HttpURLConnection) url.openConnection();
    ycConnection.setRequestMethod("POST");
    ycConnection.setDoOutput(true);
    ycConnection.setUseCaches (false);
    ycConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    PrintWriter out = new PrintWriter(ycConnection.getOutputStream());


    out.print(encodedData.getBytes());
    out.close();

    BufferedReader in = new BufferedReader(new InputStreamReader(ycConnection.getInputStream()));
    String response = in.readLine();

    Map<String, List<String>> headers = ycConnection.getHeaderFields(); 
    List<String> values = headers.get("Set-Cookie"); 
    String cookieValue = null; 
    for (java.util.Iterator<String> iter = values.iterator(); iter.hasNext(); ) {
         String v = iter.next(); 
         if (cookieValue == null)
             cookieValue = v;
         else
             cookieValue = cookieValue + ";" + v;
    }

    return new Login(cookieValue, response);
}

The most typical exception I get is:

java.io.IOException: Server returned HTTP response code: 504 for URL: http://www.reddit.com/api/login/kagnito/ at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)

But I have also received a lot of "invalid password" messages.

How might I resolve this? Been at it for hours!

Btw. This is what I'm having trouble understanding: https://github.com/reddit/reddit/wiki/API%3A-login I'm not sure how to POST this? Should it go into the header, or ? I'm not that familiar with the HTTP protocol. (Hence my project - I'm learning)

like image 987
André Snede Avatar asked Nov 14 '11 02:11

André Snede


People also ask

What is Reddit's API?

What is the Reddit API? The Reddit API (Application Programming Interface) allows you to extract data, or post to Reddit using a web application or your preferred programming language.

Is the Reddit API free?

All of the Reddit APIs listed are free to use, although the Socialgrep API — used for searching posts and comments dating back to 2010 — does come with features that are locked behind a pay wall.

Does Reddit have an open API?

Reddit has a extensive API which allows you to access a lot of the information on reddit in easy to work with json formatting. Most pages on reddit can also be accessed through json by simply adding .


1 Answers

Without delving too much into why the rest of it might not work, there is a problem in that you are:

  • Using URLEncoder to encode your post data: your post data is not going to into the URL, so do not encode it.

  • You are not setting the Content-Length header.

Here is what you should have to get started:

public static Login POST(URL url, String user, String pw) throws IOException
{

    String data=  "api_type=json&user=" + user +"&passwd="+pw;
    HttpURLConnection ycConnection = null;
    ycConnection = (HttpURLConnection) url.openConnection();
    ycConnection.setRequestMethod("POST");
    ycConnection.setDoOutput(true);
    ycConnection.setUseCaches (false);
    ycConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    ycConnection.setRequestProperty("Content-Length", data.length());

    PrintWriter out = new PrintWriter(ycConnection.getOutputStream());


    out.print(data.getBytes());
    out.close();

    BufferedReader in = new BufferedReader(new InputStreamReader(ycConnection.getInputStream()));
    String response = in.readLine();

    Map<String, List<String>> headers = ycConnection.getHeaderFields(); 
    List<String> values = headers.get("Set-Cookie"); 
    String cookieValue = null; 
    for (java.util.Iterator<String> iter = values.iterator(); iter.hasNext(); ) {
         String v = iter.next(); 
         if (cookieValue == null)
             cookieValue = v;
         else
             cookieValue = cookieValue + ";" + v;
    }

    return new Login(cookieValue, response);
}

When working with APIs like this, you should definetly install Fiddler which is HTTP debugger. You would have immediately seen the problem as your post data would look nothing like the example.

UPDATE:

Here is a little code I just threw into a test and it authenticated me just fine (obviously change myusername and mypassword to yours (don't forget to change it in the URL too):

    @Test
    public void someTest() throws IOException
    {
        URL u = new URL( "https://ssl.reddit.com/api/login/myusername" );
        login( u, "myusername", "mypassword" );
    }

    public static void login( URL url, String user, String pw ) throws IOException
    {

        String data = "api_type=json&user=" + user + "&passwd=" + pw;
        HttpURLConnection ycConnection = null;
        ycConnection = ( HttpURLConnection ) url.openConnection();
        ycConnection.setRequestMethod( "POST" );
        ycConnection.setDoOutput( true );
        ycConnection.setUseCaches( false );
        ycConnection.setRequestProperty( "Content-Type",
            "application/x-www-form-urlencoded; charset=UTF-8" );
        ycConnection.setRequestProperty( "Content-Length", String.valueOf( data.length() ) );

        DataOutputStream wr = new DataOutputStream(
            ycConnection.getOutputStream() );
        wr.writeBytes( data );
        wr.flush();
        wr.close();
        InputStream is = ycConnection.getInputStream();
        BufferedReader rd = new BufferedReader( new InputStreamReader( is ) );
        String line;
        StringBuffer response = new StringBuffer();
        while ( ( line = rd.readLine() ) != null )
        {
            response.append( line );
            response.append( '\r' );
        }
        for ( Entry< String, List< String >> r : ycConnection.getHeaderFields().entrySet() )
        {
            System.out.println( r.getKey() + ": " + r.getValue() );
        }
        rd.close();
        System.out.println( response.toString() );
    }
like image 160
Strelok Avatar answered Sep 22 '22 14:09

Strelok