2010-08-08 14 views
10

He pasado por diferentes tutoriales y este sitio web, pero no he podido encontrar una solución adecuada. Por otro lado, he visto aplicaciones que inician sesión en sitios web y solicitan más información, por lo que estoy seguro de que hay una forma de que funcione, pero tal vez mi enfoque sea incorrecto.Android: inicie sesión en el sitio web y guarde la sesión/cookie utilizando DefaultHttpClient

Aquí es lo que estoy tratando de hacer:. Quiero iniciar sesión en un sitio web que necesita la autenticación de usuarios y luego leer y analizar los sitios web que sólo son accesibles si el usuario se registra en El problema: después de registrar las credenciales de el sitio web, recibo una cookie que no parece conservarse en mi HttpClient, aunque los documentos sugieren que exactamente eso debería suceder.

He aquí algunos de mi código:

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(); 

Cuando la salida que el contenido de "cookies", todo parece estar bien (recibo una sesión):

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

Según entendí, la cookie/sesión se conservará y utilizará en mi HttpClient siempre que no la cierre.

Al leer la siguiente página (que está restringida), utilizando este código:

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 

Si la salida que la respuesta de la GET-petición (utilizando response.getStatusLine()) me sale un "200 OK", pero El análisis del sitio que se devuelve muestra que el inicio de sesión se pierde (solo recupero un formulario de inicio de sesión).

Cualquier ayuda es apreciada.

Respuesta

1

Asumiendo que su objeto httpclient es la misma en ambos casos, y suponiendo que el RESTRICTED_URL está en el mismo dominio que el LOGIN_URL, entonces yo creo que lo que tiene debería funcionar.

Es posible que desee utilizar Wireshark o un proxy o algo así para examinar las solicitudes HTTP que está realizando, para ver si la cookie se está adjuntando realmente a la solicitud. Puede ser que la cookie esté adjuntada, en cuyo caso hay algo más que está causando que su segunda solicitud falle.

+0

'httpclient' es el mismo para todas las solicitudes y las direcciones URL son a la vez en el mismo dominio (tanto sin SSL). Probaré Wireshark para descubrir qué se envía, gracias por la pista. – Select0r

+0

Lo he intentado: la cookie se adjunta a la segunda solicitud (GET) y recibo un mensaje "302 Found" que muestra la pantalla de inicio de sesión. – Select0r

+1

@ Select0r: parece que algo está mal con esa segunda solicitud (p. Ej., El servidor espera un encabezado 'Referer:'). – CommonsWare

2

En una aplicación que tengo que iniciar sesión. Primero tengo que ejecutar un GET seguido de un POST y luego el GET nuevamente. El First get creará una instancia de una ID de Jsession para mi conexión. El POST autenticará mi ID y luego el get get original devolverá el contenido real.

El código siguiente es para una aplicación que se ejecuta en 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; 
} 
0

Puede hacerlo de esta manera, aunque es más bien una solución.

@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")); 
} 
1

usted tiene que hacer DefaultHttpClient httpclient con el patrón Singleton para SessionCookie que tiene todavía mantienen la sesión de inicio de sesión.

Esta es la clase 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"); 
} 

y esta es la clase de 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; 
} 
Cuestiones relacionadas