A menos que hayamos desactivado el guardado de contraseñas, los navegadores propondrán almacenarla cuando formulario de login se presente en la pantalla.
La idea es plantear un formulario de login, ver los inconvenientes que se presentan y analizar soluciones, compatibles con casi todas las versiones de Firefox, Chrome e Internet Explorer (no puedo asegurar que lo que aquí se exponga funcione en todos los casos ni tampoco que sea para siempre).
Cuestiones genéricas a saber sobre el administrador de contraseñas de los navegadores
- Aplica solamente en el ámbito del navegador que se esté usando
- Solicita confirmación para guardar con los datos que están en los campos al momento de hacer el submit, principalmente cuando existe un input submit.
- Tiene que haber un input password para que entre en acción.
- Asocia el password al valor ingresado en el input de texto inmediatamente superior al de tipo password en el dominio en que se encuentra.
- Si no lo hubiera, o bien no tuviera un valor, entonces se asocia el password directamente al dominio en que se encuentra.
- En IE no se activa cuando el submit se realiza mediante javascript.
Formulario de login
<form action="index.cgi" method="post" id="login_form" name="login_form">
Email: <input type="text" name="e" id="email" /><br />
Password: <input type="password" name="p" id="password" /><br />
<input type="submit" value="Login" id="login_button" />
</form>
OBS: en el atributo action del formulario se indica el script que procesará los datos ingresados, en este caso index.cgi pero podría ser cualquiera.
El problema en este caso es que la clave se comunica de manera plana.
- Solución 1: Si se usara el protocolo HTTPS para la comunicación, la conexión de extremo a extremo estaría cifrada. Es lo más recomendado, pero vamos a considerar que no contamos con el certificado requerido para implementarlo y utilizamos HTTP común, a fin de hacer más interesante el ejemplo.
- Solución 2: Cifrar la clave utilizando la función criptográfica que deseen. En el ejemplo utilizaremos SHA-512 que es bastante seguro y se puede obtener rápidamente mediante javascript.
OBS: Utilizaremos el framework Prototype de javascript para simplificar el código, pero pueden utilizar javascript puro o algún otro framework como jQuery.
Para implementar la solución 2, invocamos una función cuando se realice el submit del formulario para que lo procese. En ella ciframos la clave, de manera que cuando se comuniquen los datos, la misma viaje solamente de manera cifrada.
<script type="text/javascript">
Event.observe(window, 'load', function(){
Event.observe( 'login_form', 'submit', formProcess);
});
function formProcess(){
//agregar validaciones
$('password').value = hex_sha512($('password').value);
return true;
}
</script>
OBS: Se debe reemplazar el comentario //agregar validaciones por las validaciones del lado del cliente, correspondientes al procesamiento del formulario
Un detalle de color: tal como planteamos la solución, a la vista aparecen por un instante más caracteres en el campo justo antes de empezar a cargar la página después del submit (resultado del cifrado de la clave)
Mejora visual 1: podemos agregar un input hidden:
<input type="hidden" name="ps" id="secret">
donde guardamos la clave cifrada y luego borramos el contenido del campo password (de lo contrario viajaría la clana nuevamente)
$('secret').value = hex_sha512($('password').value);
$('password').value = '';
Entonces la clave ingresada desaparece por un instante justo antes de empezar a cargar la página después del submit.
Mejora visual 2: contamos la cantidad de caracteres de la clave ingresada y los reemplazamos por el caracter ‘x’:
$('secret').value = hex_sha512($('password').value);
var pass_len = $('password').value.length;
$('password').value = Array(pass_len+1).join("x");
A la vista, no cambia nada cuando hacemos el submit, pero hemos cifrado la clave.
OBS: Si pensaron hacer un disable del input password es posible que en ciertos navegadores no proponga recordarles la contraseña (ej. chrome). La mejora 2, se podría realizar también agregando OTRO input hidden y disabled (ubicado inmediatamente despúes de password) que se complete con la clave antes de borrarla, y que el procesamiento del formulario oculte el input password y se ponga visible el disabled.
Formulario completo
A continuación les dejo el código del formulario completo:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Test Site</title>
<script type="text/javascript" src="sha512.js"></script>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
Event.observe(window, 'load', function(){
Event.observe( 'login_form', 'submit', formProcess);
});
function formProcess(){
//agregar validaciones
$('secret').value = hex_sha512($('password').value);
var pass_len = $('password').value.length;
$('password').value = Array(pass_len+1).join("x");
return true;
}
</script>
</head>
<body>
<form action="index.cgi" method="post" id="login_form" name="login_form">
Email: <input type="text" name="e" id="email" /><br />
Password: <input type="password" name="p" id="password" /><br />
<input type="hidden" name="ps" id="secret">
<input type="submit" value="Login" id="login_button" />
</form>
</body>
</html>