I am unable to use Reddit's APIs to log in
Asked Answered
S

1

5

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)

Shinleaf answered 14/11, 2011 at 2:59 Comment(1)
Check an update to my answer.Sloven
S
11

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() );
    }
Sloven answered 14/11, 2011 at 3:31 Comment(5)
Everything you said made good sense, and I have now changed to code to that. Everything that comes after out.close() except for the server response is irrelevant, that is not the problem yet, so thank you for not diving in to that. But the problem persist, I cannot get authenticated.Kenyakenyatta
Please ignore the bad spelling, haven't got that much sleep tonight.Kenyakenyatta
Thanks alot! That worked! I will read your code through and understand it, before I move on. But really, thank you!Kenyakenyatta
The best thank you on StackOverflow is accepting an answer by clicking the big tick, on the left of the answer, under the votes :) Welcome to StackOverflow. Have a read of the FAQ. Have fun :)Sloven
after login it always show not login error while using other api's like comment , subreddits etc.Coloring

© 2022 - 2024 — McMap. All rights reserved.