1

My problem:

I have an Android application. I'm using HttpURLConnection to send a POST request to a login form on an external website. The website uses cookies for logins and I want to check if my login was successful by catching the 'Set-Cookie' variable from the response header of my POST request. I'm doing this with a class that extends android's AsyncTask class.

The problem is that the HTML response I get from my request clearly states that I have cookies disables and naturally, I don't get any Set-Cookie headers because of that.

Desired result:

The printed response header fields should include the 'Set-Cookie' header. The HTML should either include a table with:

Error: 'Login failed. Both login name and password are case sensitive, check that caps lock is not enabled."

or:

Info: 'Welcome! You are now logged in'

depending on what username and password were given.

Actual result:

POST request is successful, so is getting the header. This is the result of my System.out.println:

Printing Response Header...
Key : null ,Value : [HTTP/1.1 200 OK]
Key : Connection ,Value : [close]
Key : Content-Language ,Value : [en]
Key : Content-Length ,Value : [14233]
Key : Content-Type ,Value : [text/html;charset=utf-8]
Key : Date ,Value : [Fri, 10 Jul 2015 15:32:17 GMT]
Key : Expires ,Value : [Sat, 1 Jan 2000 00:00:00 GMT]
Key : Server ,Value : [Zope/(2.13.20, python 2.7.6, linux2) ZServer/1.1]
Key : X-Android-Received-Millis ,Value : [1436542369028]
Key : X-Android-Response-Source ,Value : [NETWORK 200]
Key : X-Android-Sent-Millis ,Value : [1436542368849]
Key : X-Ua-Compatible ,Value : [IE=edge,chrome=1]

I see no Set-Cookie variable. This is unsurprising because in the HTML response, I find this in my 'Error' table:

"Cookies are not enabled. You must enable cookies to sign in."

This is the site I get if I manually disable cookies in my laptop's webbrowser and try logging in there. This is what I can't seem to fix.

Code:

The AsyncTask class is here:

import android.os.AsyncTask;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;


public class TutorWebConnectionTask extends AsyncTask<String, String, Void> {

    private final String USER_AGENT = "Mozilla/5.0 (Linux; Android 5.0.1; SAMSUNG GT-I9505 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.1 Chrome/34.0.1847.76 Mobile Safari/537.36";
    HttpURLConnection con;

    @Override
    protected Void doInBackground(String... strings) {

        try {
            String url = "http://tutor-web.net/login_form";
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            CookieHandler.setDefault(new CookieManager());

            //add reuqest header
            con.setRequestMethod("POST");
            con.setRequestProperty("User-Agent", USER_AGENT);
            con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

            String urlParameters = "__ac_username=user&__ac_password=12345";

            // Send post request
            con.setDoOutput(true);
            DataOutputStream wr = new DataOutputStream(con.getOutputStream());
            wr.writeBytes(urlParameters);
            wr.flush();
            wr.close();

            Map<String, List<String>> map = con.getHeaderFields();

            System.out.println("Printing Response Header...\n");

            for (Map.Entry<String, List<String>> entry : map.entrySet()) {
                System.out.println("Key : " + entry.getKey()
                        + " ,Value : " + entry.getValue());
            }


            int responseCode = con.getResponseCode();
            System.out.println("\nSending 'POST' request to URL : " + url);
            System.out.println("Post parameters : " + urlParameters);
            System.out.println("Response Code : " + responseCode);

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                if(inputLine.contains("enable cookies")) {System.out.println("Cookies are disabled -> " + inputLine);}
                response.append(inputLine);
            }
            in.close();

            //print result
            System.out.println(response.toString());

        }catch(Exception e) {e.printStackTrace();}

        return null;
    }
}

At the press of a button on my android application, in my mainActivity, I simply do:

TutorWebConnectionTask task = new TutorWebConnectionTask();
task.execute();

Various things I've tried doing to fix the problem:

  • Messing with USER_AGENT, keeping it as Mozilla/5.0 or making it as it is now, which is what whatsmyuseragent.com gives me when I go to the site on my phone. This site also tells me that I have cookies enabled!
  • Using CookiePolicy as ACCEPT_ALL.
  • Making sure that both 'Accept all cookies' and 'Accept third party cookies' are checked on my phone's browsers (chrome and default android browser).
  • Using httpClient apache class to do the work. That didn't work, not even when I used httpContext variable that I saw suggested in similar stackoverflow threads. I stopped using httpClient because of this thread telling me to use HttpURLConnection instead: Android HttpClient persistent cookies
  • Using CookieStore to try and grab the cookies through that.
  • Investigating what the tutor-web site is doing when it actually gives me the "You need to enable cookies" message. It seems to try to create a cookie and if it fails, it gives you this message.
  • Reading varies stackoverflow threads and trying their solutions, with no results.

None of these work. If anyone has any idea how to fix this, please help.

Community
  • 1
  • 1

2 Answers2

0

The cookie needs to be set in the application prior to the POST, otherwise it will not be seen until the second request to the server.

jobeard
  • 129
  • 6
  • That might work if the server actually managed to create any cookies. If I got a successful HTML response then I might do a GET request to the server to look for the cookie. As I said though, the HTML response I got said "You need to enable cookies" meaning the login never even went through. – user3820230 Jul 10 '15 at 16:46
  • the CGI POST moves data to the server and process logic there MUST setCookie in the reply header before anything else is returned to the client. Only the subsequent GET/POST to the server will see the cookie(s). If you test the php COOKIE[], it can be fallacious as the client has not performed its work and perhaps cookies may be denied at the users request. – jobeard Jul 11 '15 at 21:32
0

Use CookieHandler in onCreate() ( or any place where this instance gets initialize only once) as shown below:

CookieHandler.setDefault(new CookieManager());

and one more point do not set cookies yourself. So wherever you are setting properties for httpurlconnection try not to set set cookies there. It will be handled by CookieHandler internally e.g.

if(key.equalsIgnoreCase("Cookie") 
    { 
             // do nothing.
    }
    else 
    {
       conn.addRequestProperty(key,value);
    }


 // set some other properties except cookies.
  conn.connect();
durron597
  • 31,968
  • 17
  • 99
  • 158
Prasen
  • 7
  • 1
  • 8