Pase las cookies de HttpURLConnection(java.net.CookieManager) a WebView(android.webkit.CookieManager)
android-webview single-sign-on (4)
En comparación con DefaultHttpClient
, hay algunos pasos adicionales. La diferencia clave es cómo acceder a las cookies existentes en HTTPURLConnection
:
- Llame a
CookieHandler.getDefault()
yCookieHandler.getDefault()
el resultado ajava.net.CookieManager
. - Con el administrador de cookies, llame a
getCookieStore()
para acceder al almacén de cookies. - Con la tienda de cookies, llame a
get()
para acceder a la lista de cookies para elURI
dado.
Aquí hay un ejemplo completo:
@Override
protected void onCreate(Bundle savedInstanceState) {
// Get cookie manager for WebView
// This must occur before setContentView() instantiates your WebView
android.webkit.CookieSyncManager webCookieSync =
CookieSyncManager.createInstance(this);
android.webkit.CookieManager webCookieManager =
CookieManager.getInstance();
webCookieManager.setAcceptCookie(true);
// Get cookie manager for HttpURLConnection
java.net.CookieStore rawCookieStore = ((java.net.CookieManager)
CookieHandler.getDefault()).getCookieStore();
// Construct URI
java.net.URI baseUri = null;
try {
baseUri = new URI("http://www.example.com");
} catch (URISyntaxException e) {
// Handle invalid URI
...
}
// Copy cookies from HttpURLConnection to WebView
List<HttpCookie> cookies = rawCookieStore.get(baseUri);
String url = baseUri.toString();
for (HttpCookie cookie : cookies) {
String setCookie = new StringBuilder(cookie.toString())
.append("; domain=").append(cookie.getDomain())
.append("; path=").append(cookie.getPath())
.toString();
webCookieManager.setCookie(url, setCookie);
}
// Continue with onCreate
...
}
He visto respuestas sobre cómo debería funcionar esto con el antiguo
DefaultHttpClient
pero no hay un buen ejemplo paraHttpURLConnection
Estoy usando HttpURLConnection
para realizar solicitudes a una aplicación web. Al inicio de mi aplicación para Android, uso CookieHandler.setDefault(new CookieManager())
para tratar automáticamente las cookies de la sesión, y esto está funcionando bien.
En algún momento después del inicio de sesión, quiero mostrar páginas en vivo de la aplicación web al usuario con un WebView
lugar de descargar datos entre bastidores con HttpURLConnection
. Sin embargo, quiero usar la misma sesión que establecí anteriormente para evitar que el usuario tenga que volver a iniciar sesión.
¿Cómo copio las cookies de java.net.CookieManager
utilizadas por HttpURLConnection
en android.webkit.CookieManager
utilizadas por WebView
para poder compartir la sesión?
Me gustaría sugerir un enfoque completamente diferente a su problema. En lugar de copiar cookies de un lugar a otro (sincronización manual), hagamos que HttpURLConnection y WebViews utilicen el mismo almacenamiento de cookies.
Esto elimina por completo la necesidad de sincronizar. Cualquier cookie actualizada en cualquiera de ellos, se reflejará de forma inmediata y automática en el otro.
Para ello, cree su propia implementación de java.net.CookieManager, que reenvía todas las solicitudes al WebKit de WebViews android.webkit.CookieManager.
Implementación:
import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class WebkitCookieManagerProxy extends CookieManager
{
private android.webkit.CookieManager webkitCookieManager;
public WebkitCookieManagerProxy()
{
this(null, null);
}
WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy)
{
super(null, cookiePolicy);
this.webkitCookieManager = android.webkit.CookieManager.getInstance();
}
@Override
public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException
{
// make sure our args are valid
if ((uri == null) || (responseHeaders == null)) return;
// save our url once
String url = uri.toString();
// go over the headers
for (String headerKey : responseHeaders.keySet())
{
// ignore headers which aren''t cookie related
if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;
// process each of the headers
for (String headerValue : responseHeaders.get(headerKey))
{
this.webkitCookieManager.setCookie(url, headerValue);
}
}
}
@Override
public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException
{
// make sure our args are valid
if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null");
// save our url once
String url = uri.toString();
// prepare our response
Map<String, List<String>> res = new java.util.HashMap<String, List<String>>();
// get the cookie
String cookie = this.webkitCookieManager.getCookie(url);
// return it
if (cookie != null) res.put("Cookie", Arrays.asList(cookie));
return res;
}
@Override
public CookieStore getCookieStore()
{
// we don''t want anyone to work with this cookie store directly
throw new UnsupportedOperationException();
}
}
y finalmente utilícelo haciendo esto en la inicialización de su aplicación:
android.webkit.CookieSyncManager.createInstance(appContext);
// unrelated, just make sure cookies are generally allowed
android.webkit.CookieManager.getInstance().setAcceptCookie(true);
// magic starts here
WebkitCookieManagerProxy coreCookieManager = new WebkitCookieManagerProxy(null, java.net.CookiePolicy.ACCEPT_ALL);
java.net.CookieHandler.setDefault(coreCookieManager);
Resolví mágicamente todos mis problemas de cookies con esta línea en onCreate:
CookieHandler.setDefault(new CookieManager());
Tuve el mismo problema, y esta es mi solución:
Justo después de iniciar sesión (es importante porque antes, puede que aún no tenga la cookie) usando httpurlconnection POST (después de getResponseCode), hago:
responseCode = connexion.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
final String COOKIES_HEADER = "Set-Cookie";
cookie = connexion.getHeaderField(COOKIES_HEADER);
...
}
(donde cookie es una cadena pública en mi clase)
Y en la actividad de la vista web, donde quiero mostrar una página web desde el servidor usando WebView, hago:
String url = "http://toto.com/titi.html"; // the url of the page you want to display
CookieSyncManager.createInstance(getActivity());
CookieSyncManager.getInstance().startSync();
android.webkit.CookieManager cookieManager = android.webkit.CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeSessionCookie();
cookieManager.setCookie(url, cookie);
CookieSyncManager.getInstance().sync();
Como mi webview está en un fragmento, tuve que usar getActivity () para el contexto, también tuve que especificar android.webkit. antes de CookieManager, de lo contrario no se puede resolver (import java.net en lugar del administrador de cookies android.webkit).
cookie es la misma Cadena que arriba (en mi Fragmento, tuve que recuperarla usando:
cookie = getArguments().getString(COOKIE);
y en mi actividad principal, lo envío por:
Bundle arg = new Bundle();
arg.putString(Fragment_Cameras.COOKIE, cookie);
fragment.setArguments(arg);
¡Creo que esto puede ayudar!