Android: войдите на веб-сайт и сохраните сессию / cookie, используя DefaultHttpClient - PullRequest
10 голосов
/ 08 августа 2010

Я прошел через различные уроки и этот сайт, но не смог найти правильного решения.С другой стороны, я видел, как приложения заходят на веб-сайты и запрашивают дополнительную информацию, поэтому я уверен, что есть способ заставить это работать, но, возможно, мой подход совершенно неправильный.

Вот что япытаюсь сделать: я хочу войти на веб-сайт, который требует аутентификации пользователя, а затем прочитать и проанализировать веб-сайты, которые доступны, только если пользователь вошел в систему. Проблема: после размещения учетных данных на веб-сайте я получаю cookie, который неВ моем HttpClient он сохраняется, хотя в документах предполагается, что именно это должно произойти.

Вот мой код:

DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpost = new HttpPost(LOGIN_URL);

List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair(USER_FIELD, login));
nvps.add(new BasicNameValuePair(PASS_FIELD, pw));
nvps.add(new BasicNameValuePair(REMEMBERME, "on"));

httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

HttpResponse response = httpclient.execute(httpost);
HttpEntity entity = response.getEntity();

if (entity != null) {
  entity.consumeContent();
}

List<Cookie> cookies = httpclient.getCookieStore().getCookies();

Когда я выводю содержимое «куки»все выглядит нормально (я получаю сеанс):

- [version: 0][name: ASP.NET_SessionId][value: xxx][domain: xxx][path: /][expiry: null]

Как я понял, cookie / сеанс будут сохраняться и использоваться в моем HttpClient, пока я не закроюit.

При чтении следующей страницы (которая ограничена), используя этот код:

HttpGet httpget2 = new HttpGet(RESTRICTED_URL);
response = httpclient.execute(httpget2);
entity = response.getEntity();
InputStream data = entity.getContent();
// data will be parsed here
if (entity != null) {
    entity.consumeContent();
}
// connection will be closed afterwards

Если я выводлю ответ GET-запроса (используя response.getStatusLine()), я получаюСообщение «200 OK», но анализ возвращаемого сайта показывает, что вход в систему потерян (я только получаю форму входа).

Любая помощь приветствуется.

Ответы [ 4 ]

2 голосов
/ 17 мая 2011

В приложении, к которому я должен войти. Сначала я должен запустить GET, затем POST, а затем снова GET. При первом получении создается Jsession Id для моей связи. POST аутентифицирует мой ID, а затем оригинальный get GET вернет реальный контент.

Код ниже для приложения, работающего в JBoss

public boolean login() {
    HttpGet  httpGet = new HttpGet(  "http://localhost:8080/gwt-console-server/rs/identity/secure/sid/");
    HttpPost httpPost = new HttpPost("http://localhost:8080/gwt-console-server/rs/identity/secure/j_security_check");
    HttpResponse response = null;

    List<NameValuePair> nvps = new ArrayList<NameValuePair>();
    nvps.add(new BasicNameValuePair(USER_FIELD, userName));
    nvps.add(new BasicNameValuePair(PASS_FIELD, password));

    try {
        httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

        response = httpClient.execute(httpGet);
        EntityUtils.consume(response.getEntity());

        response = httpClient.execute(httpPost);
        EntityUtils.consume(response.getEntity());

        response = httpClient.execute(httpGet);
        String sessionId =EntityUtils.toString(response.getEntity());

        String cookieId =""; 
        List<Cookie> cookies = ((AbstractHttpClient) httpClient).getCookieStore().getCookies();
        for (Cookie cookie: cookies){
            if (cookie.getName().equals("JSESSIONID")){
                cookieId = cookie.getValue();
            }
        }

        if(sessionId!= null && sessionId.equals(cookieId) ){
            return true;
        }
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return false;   
}
1 голос
/ 08 августа 2012

Вы должны сделать DefaultHttpClient httpclient с одноэлементным шаблоном, чтобы sessioncookie сохранял сессию при входе.

Это класс Mainactivity:

public static DefaultHttpClient httpClient;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    RequestPage request = new RequestPage();
    request.post("http://www.example.com/login.php");

    RequestPage requestProfile =new RequestPage();
    requestProfile.post("http://www.example.com/profile.php");
}

RequestPage класс:

private InputStream post(String url){
    String paramUsername = "username";
    String paramPassword = "pass";

    if(MainActivity.httpClient==null){
        MainActivity.httpClient = new DefaultHttpClient();
    }
    DefaultHttpClient httpClient = MainActivity.httpClient;

    // In a POST request, we don't pass the values in the URL.
    //Therefore we use only the web page URL as the parameter of the HttpPost argument
    HttpPost httpPost = new HttpPost(url);

            // Because we are not passing values over the URL, we should have a mechanism to pass the values that can be
    //uniquely separate by the other end.
    //To achieve that we use BasicNameValuePair             
    //Things we need to pass with the POST request
    BasicNameValuePair usernameBasicNameValuePair = new BasicNameValuePair("username", paramUsername);
    BasicNameValuePair passwordBasicNameValuePAir = new BasicNameValuePair("password", paramPassword);

    // We add the content that we want to pass with the POST request to as name-value pairs
    //Now we put those sending details to an ArrayList with type safe of NameValuePair
    List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
    nameValuePairList.add(usernameBasicNameValuePair);
    nameValuePairList.add(passwordBasicNameValuePAir);

    try {
        // UrlEncodedFormEntity is an entity composed of a list of url-encoded pairs. 
        //This is typically useful while sending an HTTP POST request. 
        UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairList);

        // setEntity() hands the entity (here it is urlEncodedFormEntity) to the request.
        httpPost.setEntity(urlEncodedFormEntity);

        try {
            // HttpResponse is an interface just like HttpPost.
            //Therefore we can't initialize them
            HttpResponse httpResponse = httpClient.execute(httpPost);

            // According to the JAVA API, InputStream constructor do nothing. 
            //So we can't initialize InputStream although it is not an interface


            return httpResponse.getEntity().getContent();

        } catch (ClientProtocolException cpe) {
            System.out.println("First Exception caz of HttpResponese :" + cpe);
            cpe.printStackTrace();
        } catch (IOException ioe) {
            System.out.println("Second Exception caz of HttpResponse :" + ioe);
            ioe.printStackTrace();
        }

    } catch (UnsupportedEncodingException uee) {
        System.out.println("An Exception given because of UrlEncodedFormEntity argument :" + uee);
        uee.printStackTrace();
    }

    return null;
}
1 голос
/ 08 августа 2010

Если предположить, что ваш httpclient объект одинаков в обоих случаях, и предположить, что RESTRICTED_URL находится в той же области, что и LOGIN_URL, тогда я думаю, что у вас должно работать.

Возможно, вы захотите использовать Wireshark или прокси-сервер или что-то еще, чтобы проверить HTTP-запросы, которые вы делаете, чтобы увидеть, действительно ли файл cookie присоединен к запросу. Возможно, файл cookie присоединен, и в этом случае происходит что-то другое, что приводит к сбою вашего второго запроса.

0 голосов
/ 06 июля 2012

Вы можете сделать это таким образом, хотя это скорее обходной путь.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    WebView webv = (WebView)findViewById(R.id.MainActivity_webview);         
    webv.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
    });

    String postData = FIELD_NAME_LOGIN + "=" + LOGIN +
            "&" + FIELD_NAME_PASSWD + "=" + PASSWD;

    // this line logs you in and you stay logged in
    // I suppose it works this way because in this case WebView handles cookies itself
    webv.postUrl(URL, EncodingUtils.getBytes(postData, "utf-8"));
}
...