2011-11-10 14 views
10

Tengo problemas para enviar cookies como parte de un http get. Primero voy a una página de inicio de sesión dentro de una vista web que me da una cookie. Lo he verificado y la cookie se almacena en el CookieManager. Luego utilizo BasicHttpRequest para obtener una URL particular del mismo dominio. Esperaría que la cookie que obtuve del inicio de sesión se adjunte a mis encabezados para obtener, pero al mirar en Wireshark no está allí. Busqué en Google y leí muchas preguntas similares y me he asegurado de que:Compartiendo cookies de la vista web con BasicHttpRequest en Android

  • Estoy usando el CookieSyncManager así que espero que mis cookies de la sesión persistan. No creo que sea un problema con el CookieSyncManager siendo asincrónico porque sigo presionando el URL cada 5 segundos y la cookie nunca se agrega.
  • Sospecho que necesito informarle a mi solicitud de http sobre mi tienda de cookies, pero las soluciones que he buscado en Google no compilan para mí. Parece que quiero hacer algo que se parezca a context.setAttribute (ClientContext.COOKIE_STORE, this.cookieStore), pero no puedo encontrar la forma de obtener el CookieStore predeterminado del CookieManager. Algunos códigos parecen llamar a cookieManager.getCookieStore() pero eso no compila para mí en Android. Al mirar los documentos, no veo la forma de obtener el CookieStore que parece enojado. ¿Me falta algo obvio?

Mi código para poner en marcha la página de inicio de sesión en mi vista web se ve como:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // use cookies to remember a logged in status 
    CookieSyncManager.createInstance(this); 
    CookieSyncManager.getInstance().startSync(); 

    //not sure if I need to do this 
    CookieManager cookie_manager = CookieManager.getInstance(); 
    cookie_manager.setAcceptCookie(true); 

    webview = new WebView(this); 
    webview.getSettings().setJavaScriptEnabled(true); 
    webview.setWebViewClient(new HelloWebViewClient()); // if user clicks on a url we need to steal that click, also steal the back button 
    webview.loadUrl("http://"+my_server+"/api/v1/login"); 
    setContentView(webview); 

Entonces mi código para comprobar la cookie es no es así:

public static boolean CheckAuthorised() { 
    CookieSyncManager.getInstance().sync(); 
    CookieManager cookie_manager = CookieManager.getInstance(); 

    String cookie_string = cookie_manager.getCookie("http://"+my_server+"/api/v1/login"); 
    System.out.println("lbp.me cookie_string: " + cookie_string); 

    if(cookie_string != null) 
    { 
     String[] cookies = cookie_string.split(";"); 
     for (String cookie : cookies) 
     { 
      if(cookie.matches("API_AUTH=.*")) 
      { 
       // maybe we need to store the cookie for the root of the domain? 
       cookie_manager.setCookie("http://"+my_server, cookie_string); 
       // maybe we need to store the cookie for the url we're actually going to access? 
       cookie_manager.setCookie("http://"+my_server+"/api/v1/activity", cookie_string);  

       CookieSyncManager.getInstance().sync(); 
       return true; 
      } 
     } 
    } 

    return false; 
} 

Y para hacer realidad la solicitud http I do

public static HttpResponse getMeAWebpage(String host_string, int port, String url) 
     throws Exception { 
    HttpParams params = new BasicHttpParams(); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
    HttpProtocolParams.setContentCharset(params, "UTF-8"); 
    HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1"); 
    HttpProtocolParams.setUseExpectContinue(params, true); 

    BasicHttpProcessor httpproc = new BasicHttpProcessor(); 
    // Required protocol interceptors 
    httpproc.addInterceptor(new RequestContent()); 
    httpproc.addInterceptor(new RequestTargetHost()); 
    // Recommended protocol interceptors 
    httpproc.addInterceptor(new RequestConnControl()); 
    httpproc.addInterceptor(new RequestUserAgent()); 
    httpproc.addInterceptor(new RequestExpectContinue()); 

    HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); 

    HttpContext context = new BasicHttpContext(null); 
    // HttpHost host = new HttpHost("www.svd.se", 80); 
    HttpHost host = new HttpHost(host_string, port); 

    DefaultHttpClientConnection conn = new DefaultHttpClientConnection(); 
    ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy(); 

    context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); 
    context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host); 
    //CookieManager cookie_manager = CookieManager.getInstance(); 
    //CookieStore cookie_store = cookie_manager.getCookieStore(); //The method getCookieStore() is undefined for the type CookieManager 
    //context.setAttribute(ClientContext.COOKIE_STORE, cookie_store); 

    HttpResponse response = null; 

    try { 
     if (!conn.isOpen()) { 
      Socket socket = new Socket(host.getHostName(), host.getPort()); 
      conn.bind(socket, params); 
     } 

     BasicHttpRequest request = new BasicHttpRequest("GET", url); 
     System.out.println(">> Request URI: " 
       + request.getRequestLine().getUri()); 
     System.out.println(">> Request: " 
       + request.getRequestLine()); 

     request.setParams(params); 
     httpexecutor.preProcess(request, httpproc, context); 
     response = httpexecutor.execute(request, conn, context); 
     response.setParams(params); 
     httpexecutor.postProcess(response, httpproc, context); 

     String ret = EntityUtils.toString(response.getEntity()); 
     System.out.println("<< Response: " + response.getStatusLine()); 
     System.out.println(ret); 
     System.out.println("=============="); 
     if (!connStrategy.keepAlive(response, context)) { 
      conn.close(); 
     } else { 
      System.out.println("Connection kept alive..."); 
     } 
    } catch(UnknownHostException e) { 
     System.out.println("UnknownHostException"); 
    } catch (HttpException e) { 
     System.out.println("HttpException"); 
    } finally { 
     conn.close(); 
    } 

    return response; 
} 

gracias por readin g tan lejos! Cualquier sugerencia recibida con gratitud,

Amy

+0

¿Has probado params.setParameter ("cookie", cookie)? mientras que la cookie es la Cookie válida de su CookieStore. –

+0

Hola Franziskus, acabo de probar params.setParameter ("cookie", cookie), y puedo ver que params ahora tiene 5 entradas, pero la parte de cookie nunca llega al http get como se ve usando Wireshark. –

Respuesta

3

Colocación de las galletas finalmente está trabajando para mí! Puede que no lo haya hecho de la manera más fácil, pero al menos funciona. Mi gran avance fue descargar y conectar las fuentes de Android, para poder pasar y ver qué estaba pasando. Aquí hay instrucciones http://blog.michael-forster.de/2008/12/view-android-source-code-in-eclipse.html - desplácese hacia abajo y lea el comentario de Volure para la descarga más simple. Recomiendo encarecidamente hacer esto si está desarrollando en Android.

Ahora en el código de cookies de trabajo - la mayoría de los cambios estaban en el código que realmente me da mi página web - tuve que configurar una COOKIE_STORE y una COOKIESPEC_REGISTRY. Entonces yo también tenía que cambiar mi tipo de conexión debido a que el código de galletas estaba echando a un ManagedClientConnection:

public static HttpResponse getMeAWebpage(String host_string, int port, String url) 
     throws Exception { 
    HttpParams params = new BasicHttpParams(); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
    HttpProtocolParams.setContentCharset(params, "UTF-8"); 
    HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1"); 
    HttpProtocolParams.setUseExpectContinue(params, true); 
    //params.setParameter("cookie", cookie); 

    BasicHttpProcessor httpproc = new BasicHttpProcessor(); 
    // Required protocol interceptors 
    httpproc.addInterceptor(new RequestContent()); 
    httpproc.addInterceptor(new RequestTargetHost()); 
    // Recommended protocol interceptors 
    httpproc.addInterceptor(new RequestConnControl()); 
    httpproc.addInterceptor(new RequestUserAgent()); 
    httpproc.addInterceptor(new RequestExpectContinue()); 
    httpproc.addInterceptor(new RequestAddCookies()); 


    HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); 

    HttpContext context = new BasicHttpContext(null); 
    // HttpHost host = new HttpHost("www.svd.se", 80); 
    HttpHost host = new HttpHost(host_string, port); 
    HttpRoute route = new HttpRoute(host, null, false); 

    // Create and initialize scheme registry 
    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
    schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); 

    SingleClientConnManager conn_mgr = new SingleClientConnManager(params, schemeRegistry); 
    ManagedClientConnection conn = conn_mgr.getConnection(route, null /*state*/); 
    ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy(); 

    context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); 
    context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host); 

    CookieStore cookie_store = new BasicCookieStore(); 
    cookie_store.addCookie(cookie); 
    context.setAttribute(ClientContext.COOKIE_STORE, cookie_store); 

    // not sure if I need to add all these specs, but may as well 
    CookieSpecRegistry cookie_spec_registry = new CookieSpecRegistry(); 
    cookie_spec_registry.register(
      CookiePolicy.BEST_MATCH, 
      new BestMatchSpecFactory()); 
    cookie_spec_registry.register(
      CookiePolicy.BROWSER_COMPATIBILITY, 
      new BrowserCompatSpecFactory()); 
    cookie_spec_registry.register(
      CookiePolicy.NETSCAPE, 
      new NetscapeDraftSpecFactory()); 
    cookie_spec_registry.register(
      CookiePolicy.RFC_2109, 
      new RFC2109SpecFactory()); 
    cookie_spec_registry.register(
      CookiePolicy.RFC_2965, 
      new RFC2965SpecFactory()); 
    //cookie_spec_registry.register(
    //  CookiePolicy.IGNORE_COOKIES, 
    //  new IgnoreSpecFactory()); 
    context.setAttribute(ClientContext.COOKIESPEC_REGISTRY, cookie_spec_registry); 

    HttpResponse response = null; 

    try { 
     if (!conn.isOpen()) { 
      conn.open(route, context, params); 
     } 

     BasicHttpRequest request = new BasicHttpRequest("GET", url); 
     System.out.println(">> Request URI: " 
       + request.getRequestLine().getUri()); 
     System.out.println(">> Request: " 
       + request.getRequestLine()); 

     request.setParams(params); 
     httpexecutor.preProcess(request, httpproc, context); 
     response = httpexecutor.execute(request, conn, context); 
     response.setParams(params); 
     httpexecutor.postProcess(response, httpproc, context); 

     String ret = EntityUtils.toString(response.getEntity()); 
     System.out.println("<< Response: " + response.getStatusLine()); 
     System.out.println(ret); 
     System.out.println("=============="); 
     if (!connStrategy.keepAlive(response, context)) { 
      conn.close(); 
     } else { 
      System.out.println("Connection kept alive..."); 
     } 
    } catch(UnknownHostException e) { 
     System.out.println("UnknownHostException"); 
    } catch (HttpException e) { 
     System.out.println("HttpException"); 
    } finally { 
     conn.close(); 
    } 

    return response; 
} 

Mi código para configurar mis vidas de galletas en la misma clase que getMeAWebpage() se parece a:

public static void SetCookie(String auth_cookie, String domain) 
{ 
    String[] cookie_bits = auth_cookie.split("="); 
    cookie = new BasicClientCookie(cookie_bits[0], cookie_bits[1]); 
    cookie.setDomain(domain); // domain must not have 'http://' on the front 
    cookie.setComment("put a comment here if you like describing your cookie"); 
    //cookie.setPath("/blah"); I don't need to set the path - I want the cookie to apply to everything in my domain 
    //cookie.setVersion(1); I don't set the version so that I get less strict checking for cookie matches and am more likely to actually get the cookie into the header! Might want to play with this when you've got it working... 
} 

Realmente espero que esto te ayude si tienes problemas similares. ¡Siento como si hubiera estado golpeándome la cabeza contra la pared durante un par de semanas! Ahora, para una merecida taza de té de celebración: o)

Cuestiones relacionadas