2010-08-08 4 views
10

Ich habe durch verschiedene Tutorials und diese Website, konnte aber keine richtige Lösung finden. Auf der anderen Seite habe ich gesehen, wie sich Apps in Websites einloggt und weitere Informationen anfordert. Ich bin mir sicher, dass es einen Weg gibt, das zum Laufen zu bringen, aber vielleicht ist meine Vorgehensweise falsch.Android: Einloggen in die Website und Bewahren Session/Cookie mit DefaultHttpClient

Hier ist, was ich versuche: Ich möchte auf einer Website anmelden, die Benutzerauthentifizierung benötigt und dann lesen und analysieren Websites, die nur zugänglich sind, wenn der Benutzer angemeldet ist. Das Problem: nach dem Anmeldeschluss an Auf der Website erhalte ich einen Cookie, der in meinem HttpClient nicht erhalten zu sein scheint, obwohl die Dokumente vermuten lassen, dass genau das passieren soll.

Hier einige meiner Code:

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

Wenn ich Ausgang der Inhalt von "Cookies", alles in Ordnung scheint (I erhalten eine Sitzung):

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

Wie ich verstanden, Der Cookie/die Sitzung wird beibehalten und in meinem HttpClient verwendet, solange ich ihn nicht schließe.

Wenn die nächste Seite zu lesen (das beschränkt ist), diesen Code verwenden:

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 

Wenn ich Ausgabe der Antwort des GET-Request (mit response.getStatusLine()) ich eine "200 OK" Nachricht erhalten, aber Parsing der Website, die zurückgegeben wird, zeigt, dass die Anmeldung verloren ist (ich nur ein Login-Formular abrufen).

Jede Hilfe wird geschätzt.

Antwort

1

Angenommen, Ihr Objekt ist in beiden Fällen das gleiche, und unter der Annahme, RESTRICTED_URL ist in der gleichen Domäne wie die LOGIN_URL, dann würde ich denken, was Sie haben, sollte funktionieren.

Sie möchten möglicherweise Wireshark oder einen Proxy oder etwas verwenden, um die HTTP-Anfragen zu untersuchen, die Sie machen, um zu sehen, ob der Cookie tatsächlich an die Anfrage angehängt wird. Es kann sein, dass der Cookie angehängt wird. In diesem Fall gibt es einen anderen Fehler, der Ihre zweite Anfrage fehlschlagen lässt.

+0

'httpclient' ist das gleiche für alle Anforderungen und die URLs sind beide auf der gleichen Domain (beide ohne SSL). Ich werde versuchen, Wireshark herauszufinden, was gesendet wird, danke für den Hinweis. – Select0r

+0

Ich habe es ausprobiert: der Cookie ist an die zweite (GET) Anfrage angehängt und ich erhalte eine "302 Found" -Meldung, die den Login-Bildschirm anzeigt. – Select0r

+1

@ Select0r: klingt wie etwas anderes ist dann falsch mit dieser zweiten Anfrage (z. B. Server erwartet eine 'Referer:' Header). – CommonsWare

2

In einer Anwendung, die ich anmelden muss. Zuerst muss ich ein GET gefolgt von einem POST und dann das GET erneut ausführen. Das erste get wird eine Jsession Id für meine Verbindung instanziieren. Der POST authentifiziert meine ID und das ursprüngliche get GET gibt den tatsächlichen Inhalt zurück.

Der folgende Code ist für eine Anwendung in JBoss läuft

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

Sie es auf diese Weise tun können, obwohl es eher eine Abhilfe.

@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

Sie haben DefaultHttpClient httpclient mit Singletonmuster so Sessioncookie, die Sie noch Sitzung vom Login halten müssen machen.

Dies ist die Mainactivity Klasse:

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

und dies ist die RequestPage Klasse:

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; 
} 
Verwandte Themen