Problemas con la autenticación de formularios ASP.NET en Phonegap (Android)

Tengo un backend de ASP.NET MVC / Web API donde he implementado una autenticación de formularios para mi aplicación Phonegap. El inicio de sesión se ejecuta mediante el envío de las credenciales de los usuarios a través de jQuery llamada Ajax como este:

$.ajax({ type: "POST", url: "/api/authentication/login", data: JSON.stringify({ Username: username, Password: password }), contentType: "application/json; charset=utf-8", dataType: "TEXT", statusCode: { 200: function (response, status, xhr) { // successfully authenticated Backbone.history.navigate("/", { trigger: true }); } } }); 

El método de inicio de sesión de backends se ve así:

 [ActionName("login")] [AllowAnonymous] public LoginResult Login(LoginCredentials credentials) { // doing all kinds of things here // if valid credentials FormsAuthentication.SetAuthCookie(loginID, true); return loginResult; } 

Tengo esto en mi Web.config:

 <authentication mode="Forms"> <forms name=".ASPXAUTH" loginUrl="/login" defaultUrl="/home" protection="All" slidingExpiration="true" timeout="525600" cookieless="UseCookies" enableCrossAppRedirects="false" requireSSL="true" > </forms> </authentication> 

Ahora el problema con Android es que la cookie está correctamente configurada y funciona en mis métodos autorizados después del inicio de sesión, pero a veces (a menudo) cuando cierro la aplicación y la vuelvo a abrir, ya no estoy conectado. Ya no existe, no puedo verlo en la solicitud. Esto no debería suceder porque he establecido el tiempo de espera en 525600. He notado que este problema a menudo se produce cuando cierro la aplicación inmediatamente después de iniciar sesión. Por otro lado, si salgo y luego inicie sesión sin cerrar la aplicación, la cookie se guarda correctamente.

Pero, si consigo que la galleta se pegue, la mayor parte del tiempo el logout se comporta extrañamente también. Así es como hago la solicitud de cierre de sesión:

 $.ajax({ type: "POST", url: "/api/authentication/logout", data: "{}", contentType: "application/json; charset=utf-8", dataType: "text" success: function (response) { // successfully logged out Backbone.history.navigate("api/login", { trigger: true }); } }); 

El backend:

 [ActionName("logout")] [AllowAnonymous] public String Logout() { FormsAuthentication.SignOut(); HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, ""); cookie.Expires = DateTime.Now.AddYears(-1); HttpContext.Current.Response.Cookies.Add(cookie); return "home"; } 

Ahora, similar al problema con el inicio de sesión, el cierre de sesión primero parece tener éxito y la cookie ya no se envía con ninguna solicitud. Pero cuando cierro la aplicación y la vuelvo a abrir, la cookie está de vuelta y vuelvo a iniciar sesión. Puedo ver que la galleta tiene el mismo valor que el que creí que acabo de quitar fijando su tiempo de la expiración al pasado.

He intentado todo tipo de trucos, como:

  • Recargas adicionales después del inicio de sesión / cierre de sesión ( location.reload() )
  • Ejecución de la solicitud de cierre de sesión / inicio de sesión varias veces
  • Ejecutar la solicitud a otros métodos después del inicio de sesión / cierre de sesión
  • 1-10 segundo tiempo de espera entre la petición de inicio de sesión / cierre de sesión y la recarga
  • Todo tipo de variaciones de lo anterior

La autenticación funciona según lo previsto en iOS y Windows Phone. El problema se produce sólo en Android (probado en KitKat y Lollipop). No hay problema en el emulador de Android, pero en los dispositivos reales y Visual Studios emulador de Android que esto sucede todo el tiempo.

No sé en qué dirección ir desde aquí. ¿Hay algo en el Android WebView que podría causar este tipo de comportamiento? ¿Hay algo más que pueda probar? ¡Por favor ayuda!

Estoy más que feliz de dar más información si es necesario.

EDIT: Inspirado por el comentario de Fabian, cambié el método de logout a esto:

 FormsAuthentication.SignOut(); HttpCookie cookie = HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName]; cookie.Expires = DateTime.Now.AddYears(-1); HttpContext.Current.Response.Cookies.Clear(); HttpContext.Current.Response.Cookies.Add(cookie); return "home"; 

En lugar de crear una nueva cookie, usé la de la respuesta. No funcionó.

También intenté algo que encontré de aquí: http://techblog.dorogin.com/2013/01/formsauthentication-gotcha-with-signout.html Eso también no hizo ninguna diferencia, la trayectoria no era el problema. Todavía estamos buscando una solución.

OTRO EDIT: Todavía no es capaz de encontrar una solución para esto. Tuve que hacer una horrible solución.

  • Login: Hago dos recargas después del inicio de sesión y luego una solicitud a un método ficticio. Esto parece funcionar cada vez.
  • Logout: Utilizo una bandera colocada en localStorage para determinar si el usuario ha cerrado una sesión y realizar un logout en la puesta en marcha. Esto siempre quita la cookie correctamente.

No estoy contento con estos hacks y todavía estoy esperando una mejor solución.

PhoneGap carga archivos desde file:// protocolo file:// . Desafortunadamente, las peticiones de origen cruzadas no están permitidas ya menos que abra solicitudes de origen cruzadas de todos los hosts * , este problema no se resolverá.

Hay varias maneras en que esto puede arreglarse, pero son realmente largas.

Cargar HTML desde http://

Cargar el sitio web completo desde el servidor web en lugar del almacenamiento local. Esto elimina todos los problemas con peticiones de origen cruzadas. El beneficio es que no es necesario publicar una nueva versión de la aplicación cuando cambie la interfaz de usuario. Pero tendrá que implementar caché muy potente y la primera vez que abra la aplicación tardará más tiempo.

Interceptar http:// y entregar archivos locales

Como sabes, phonegap simplemente usa WebView, en todas las plataformas, puedes simplemente anular el protocolo Url para inyectar archivos desde el almacenamiento local de tu aplicación. Esto será más rápido, y el navegador pensará que está cargando html desde el mismo recurso.

Configurar el encabezado personalizado OAuth + para la autenticación

  1. Redireccione a una página de inicio de sesión alojada en su sitio web, diga http://domain.com/api/login
  2. Después de una conexión correcta, use PhoneGap localStorage (no localStorage del navegador) para almacenar la autorización.
  3. Navegue a las páginas html locales desde la aplicación y para cada solicitud de json api que envíe al servidor, envíe el encabezado de autorización como encabezado independiente en la solicitud de ajax.
  4. Configure un módulo de autorización, donde puede autorizar manualmente la solicitud de asp.net si su autorización se envió a través del encabezado personalizado en la solicitud http

Creo que he encontrado la solución. La versión de Phonegap en su archivo config.xml es cli-5.1.1 , que incluye Android Phonegap versión 4.0.2 según la documentación .

El problema con las versiones es que parece que el equipo Android Phonegap eventualmente arregló el problema de almacenamiento de cookies en la versión 5.2.0 . Se puede encontrar en notas de lanzamiento como:

CB-10896 Nunca hemos habilitado las cookies en WebView correctamente

Por lo tanto, actualizar su Phonegap a la versión más reciente debería solucionar el problema.

Según MSDN :

El método FormsAuthentication.SignOut elimina la información de ticket de autenticación de formularios de la cookie.

Y eso es todo lo que necesita para registrar el usuario. No es necesario que expire o elimine la cookie. Simplemente cambia tu Logout() a:

 [ActionName("logout")] [AllowAnonymous] public String Logout() { FormsAuthentication.SignOut(); return "home"; } 
  • Cómo jugar video HTML5 en línea con Phonegap para Android 4.1.1
  • La aplicación Build con Herramientas para Apache Cordova falla
  • Los permisos de ACCESS_FINE_LOCATION se actualizan con uses-feature en la aplicación móvil de Ionic
  • VS2013 Cordova comando de la aplicación en blanco falló con código de salida 8 error
  • Recorta la imagen de la cámara antes de subirla (Phonegap)
  • Inter-dispositivo de comunicación a través de Bluetooth con Phonegap en Android?
  • Cordova CLI Phone Gap Aplicación navigator.app.exit Función no funciona
  • Velocidad de PhoneGap vs iOS 4/5 nativo y Android para GPS / Servicios de ubicación / Mapas
  • Cerrar la barra de estado cuando se hace clic en la notificación de botón
  • Antecedentes Phonegap y la relación entre ciclos de vida de actividad, proceso y servicio
  • HTML5 SQLite vs Base de datos nativa en caso de PhoneGap
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.