Pregunta Problema de cookies de Android WebView


Tengo un servidor que envía mi aplicación de Android una cookie de sesión para ser utilizada comunicación autenticada Estoy intentando cargar un WebView con una URL apuntando a ese mismo servidor y estoy tratando de pasar la sesión cookie para autenticación. Estoy observando que funciona intermitentemente, pero no tengo idea de por qué. Utilizo la misma cookie de sesión para hacer otras llamadas en mi servidor y estas nunca fallan la autenticación. Solo observo este problema cuando trato de cargar una URL en un WebView, y esto no ocurre siempre. Muy frustrante.

A continuación está el código que estoy usando para hacer esto. Cualquier ayuda será apreciada.

String myUrl = ""http://mydomain.com/"; 
CookieSyncManager.createInstance(this); 
CookieManager cookieManager = CookieManager.getInstance(); 
Cookie sessionCookie =  getCookie(); 
if(sessionCookie != null){ 
    String cookieString = sessionCookie.getName() +"="+sessionCookie.getValue()+"; domain="+sessionCookie.getDomain(); 
    cookieManager.setCookie(myUrl, cookieString); 
    CookieSyncManager.getInstance().sync(); 
} 

WebView webView = (WebView) findViewById(R.id.webview); 
webView.getSettings().setBuiltInZoomControls(true); 
webView.getSettings().setJavaScriptEnabled(true); 
webView.setWebViewClient(new MyWebViewClient()); 
webView.loadUrl(myUrl);

74
2017-10-30 23:51


origen


Respuestas:


Gracias justingrammens! Eso funcionó para mí, logré compartir la cookie dentro de mis peticiones de DefaultHttpClient y la actividad de WebView:

//------- Native request activity
private DefaultHttpClient httpClient;
public static Cookie cookie = null;

//After Login
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
    cookie = cookies.get(i);
}

//------- Web Browser activity
Cookie sessionCookie = myapp.cookie;
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
if (sessionCookie != null) {
    cookieManager.removeSessionCookie();
    String cookieString = sessionCookie.getName() + "=" + sessionCookie.getValue() + "; domain=" + sessionCookie.getDomain();
    cookieManager.setCookie(myapp.domain, cookieString);
    CookieSyncManager.getInstance().sync();
}   

47
2018-02-27 23:13



Solución: Webview CookieSyncManager

CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(mWebView.getContext());
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeSessionCookie();
cookieManager.setCookie("http://xx.example.com","mid="+MySession.GetSession().sessionId+" ; Domain=.example.com");
cookieSyncManager.sync();

String cookie = cookieManager.getCookie("http://xx.example.com");

Log.d(LOGTAG, "cookie ------>"+cookie);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new TuWebViewClient());
mWebView.loadUrl("http://xx.example.com");

13
2018-06-27 20:32



la solución es darle a Android suficiente tiempo para procesar las cookies. Puedes encontrar más información aquí: http://code.walletapp.net/post/46414301269/passing-cookie-to-webview


8
2018-04-18 13:09



Gracias a Android por arruinar mi domingo. . . Aquí está lo que solucionó mis aplicaciones (después de iniciar su página web)

if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) {

  CookieManager cookieManager = CookieManager.getInstance();

  cookieManager.setAcceptThirdPartyCookies( webView, true );

}

Debo decir que las respuestas anteriores probablemente funcionen, pero en mi situación, en el momento en que Android pasó v5 +, mi aplicación web android javascript 'apps' murió.


8
2018-01-17 07:33



Pasé la mayor parte de las 3 horas trabajando en un problema muy similar. En mi caso, tuve varias llamadas que hice a un servicio web usando una DefaulHttpClient y luego quería configurar la sesión y todas las demás cookies correspondientes en mi WebView.

No sé si esto resolverá tu problema, ya que no sé cuál es tu getCookie() método lo hace, pero en mi caso tuve que llamar.

cookieManager.removeSessionCookie();

Primero, elimine la cookie de sesión y luego vuélvala a agregar. Estaba encontrando eso cuando traté de configurar el JSESSIONID cookie sin eliminarlo primero, el valor al que quería establecerlo no era guardar. No estoy seguro si esto lo ayudará con un problema en particular, pero pensé que compartiría lo que había encontrado.


3
2018-01-23 03:13



Guardaría esa cookie de sesión como preferencia y repoblaré forzosamente el administrador de cookies con ella. Suena que la cookie de sesión no se conserva.


2
2017-10-31 00:03



Tengo un enfoque diferente de otras personas aquí, y es un enfoque que garantiza el trabajo sin tener que lidiar con el CookieSyncManager (donde está a merced de la semántica como "Tenga en cuenta que incluso la sincronización () ocurre de forma asíncrona").

Básicamente, buscamos el dominio correcto, luego ejecutamos javascript desde el contexto de la página para establecer cookies para ese dominio (de la misma manera que lo haría la página). Dos inconvenientes del método son que puede introducir un tiempo de ida y vuelta adicional debido a la solicitud HTTP adicional que debe realizar; y si su sitio no tiene el equivalente de una página en blanco, puede mostrar cualquier URL que cargue antes de llevarlo al lugar correcto.

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.cookie.Cookie;
import android.annotation.SuppressLint;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class WebViewFragment {
    private static final String BLANK_PAGE = "/blank.html"

    private CookieSyncManager mSyncManager;
    private CookieManager mCookieManager;

    private String mTargetUrl;
    private boolean mInitializedCookies;
    private List<Cookie> mAllCookies;

    public WebViewFragment(Context ctx) {
        // We are still required to create an instance of Cookie/SyncManager.
        mSyncManager = CookieSyncManager.createInstance(ctx);
        mCookieManager = CookieManager.getInstance();
    }

    @SuppressLint("SetJavaScriptEnabled") public void loadWebView(
                String url, List<Cookie> cookies, String domain) {
        final WebView webView = ...

        webView.setWebViewClient(new CookeWebViewClient());
        webView.getSettings().setJavaScriptEnabled(true);

        mInitializedCookies = false;
        mTargetUrl = url;
        mAllCookies = cookies;
        // This is where the hack starts.
        // Instead of loading the url, we load a blank page.
        webView.loadUrl("http://" + domain + BLANK_PAGE);
    }

    public static String buildCookieString(final Cookie cookie) {
        // You may want to add the secure flag for https:
        // + "; secure"
        // In case you wish to convert session cookies to have an expiration:
        // + "; expires=Thu, 01-Jan-2037 00:00:10 GMT"
        // Note that you cannot set the HttpOnly flag as we are using
        // javascript to set the cookies.
        return cookie.getName() + "=" + cookie.getValue()
                    + "; path=" + cookie.getPath()
                    + "; domain=" + cookie.getDomain()
    };

    public synchronized String generateCookieJavascript() {
        StringBuilder javascriptCode = new StringBuilder();
        javascriptCode.append("javascript:(function(){");
        for (final Cookie cookie : mAllCookies) {
            String cookieString = buildCookieString(cookie);
            javascriptCode.append("document.cookie=\"");
            javascriptCode.append(
                     StringEscapeUtils.escapeJavascriptString(cookieString));
            javascriptCode.append("\";");
        }
        // We use javascript to load the next url because we do not
        // receive an onPageFinished event when this code finishes.
        javascriptCode.append("document.location=\"");
        javascriptCode.append(
                StringEscapeUtils.escapeJavascriptString(mTargetUrl));
        javascriptCode.append("\";})();");
        return javascriptCode.toString();
    }

    private class CookieWebViewClient extends WebViewClient {
        @Override public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (!mInitializedCookies) {
                mInitializedCookies = true;
                // Run our javascript code now that the temp page is loaded.
                view.loadUrl(generateCookieJavascript());
                return;
            }
        }
    }
}

Si confía en el dominio de donde provienen las cookies, puede escapar sin apache commons, pero debe comprender que esto puede presentar un riesgo XSS si no tiene cuidado.


1
2018-04-02 19:02



Este es un código de código funcional.

    private void setCookie(DefaultHttpClient httpClient, String url) {
    List<Cookie> cookies = httpClient.getCookieStore().getCookies();
    if (cookies != null) {
        CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);

        for (int i = 0; i < cookies.size(); i++) {
            Cookie cookie = cookies.get(i);
            String cookieString = cookie.getName() + "=" + cookie.getValue();
            cookieManager.setCookie(url, cookieString);
        }
        CookieSyncManager.getInstance().sync();
    }
}

Aquí el httpclient es el objeto DefaultHttpClient que usaste en la solicitud HttpGet / HttpPost. También una cosa para asegurarse es el nombre y el valor de la cookie, se debe dar

String cookieString = cookie.getName() + "=" + cookie.getValue();

setCookie establecerá la cookie para la URL dada.


1
2017-08-06 10:30



Resolví mágicamente todos mis problemas de cookies con esta línea en onCreate:

CookieHandler.setDefault(new CookieManager());

editar: dejó de funcionar hoy. :( qué mierda, android.


1
2017-10-18 19:18



Encontré esto también también. Esto es lo que hice.

En mi LoginActivity, dentro de mi AsyncTask, tengo lo siguiente:

CookieStoreHelper.cookieStore = new BasicCookieStore();
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, CookieStoreHelper.cookieStore);

HttpResponse postResponse = client.execute(httpPost,localContext);
CookieStoreHelper.sessionCookie = CookieStoreHelper.cookieStore.getCookies();

// WHERE CookieStoreHelper.sessionCookie es otra clase que contiene la variable sessionCookie definida como List cookies; y cookieStore define como BasicCookieStore cookieStore;

Luego, en mi Fragmento, donde se encuentra mi WebView, tengo lo siguiente:

//DECLARE LIST OF COOKIE
List<Cookie> sessionCookie;

dentro de mi método o justo antes de configurar el WebViewClient ()

WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);

sessionCookie = CookieStoreHelper.cookieStore.getCookies();
CookieSyncManager.createInstance(webView.getContext());
CookieSyncManager.getInstance().startSync();
CookieManager cookieManager = CookieManager.getInstance();
CookieManager.getInstance().setAcceptCookie(true);
if (sessionCookie != null) {
   for(Cookie c:  sessionCookie){
      cookieManager.setCookie(CookieStoreHelper.DOMAIN, c.getName() + "=" + c.getValue());
   }
   CookieSyncManager.getInstance().sync();

 }

 webView.setWebViewClient(new WebViewClient() {
    //AND SO ON, YOUR CODE
 }

Consejo rápido: Instale Firebug en Firefox o use la consola de desarrollador en Chrome y pruebe primero su página web, capture las cookies y verifique el dominio para poder almacenarlo en algún lugar y asegurarse de que está configurando correctamente el dominio correcto.

Editar: editado CookieStoreHelper.cookies a CookieStoreHelper.sessionCookie


1
2017-11-07 07:57