Citas sobre la usabilidad

En la página  web The ROI of Usability hay numerosas citas de casos reales que demuestran la importancia de la usabilidad. Algunas de estas citas son:

“The rule of thumb in many usability-aware organizations is that the cost-benefit ratio for usability is $1:$10-$100. Once a system is in development, correcting a problem costs 10 times as much as fixing the same problem in design. If the system has been released, it costs 100 times as much relative to fixing in design.” (Gilb, 1988)

 

“You can increase sales on your site as much as 225% by providing sufficient product information to your customers at the right time. In our recent research, we found that the design of product lists directly affected sales. On sites that did not require shoppers to bounce back-and-forth between the list and individual product pages, visitors added more products to their shopping cart and had a more positive opinion of the site. By understanding your customer expectations and needs, and designing your product lists accordingly, you can significantly increase your sales.” (UI Engineering, 2001)

 

“More than 83 percent of Internet users are likely to leave a Web site if they feel they have to make too many clicks to find what they’re looking for, according to Andersen’s latest Internet survey.” (Arthur Andersen, 2001)

 

“A bad design can cost a Web site 40 percent of repeat traffic. A good design can keep them coming back. A few tests can make the difference.”(Kalin, 1999)

El copyright

Recientemente he vuelto a releer el libro Copia este libro (descarga en PDF), de David Bravo. Aunque se publicó en el año 2005, su vigencia es total, aunque hay algunas cosas que afortunadamente han cambiado: Teddy Bautista, el antiguo jefe supremo de la SGAE, está encausado (Teddy Bautista y dos directivos de la SGAE, imputados por apropiación indebida y administración fraudulenta) y Pedro Farre, antiguo directivo, también podría ir a la cárcel (Detenido el exjefe de gabinete de Teddy Bautista por presunto uso de la tarjeta de la SGAE en prostitución, El fiscal pide cárcel a un directivo de la SGAE por cargar a la entidad 40.000 euros en clubes de alterne).

Sobran las palabras: los que acusaban a todo el mundo de piratas, eran los verdaderos piratas 🙂

Los derechos de autor y el copyright tienen su sentido, pero ese sentido se ha llevado a unos “límites infinitos”. Que los descendientes de un autor sigan disfrutando de los derechos de autor cuando éste ya ha muerto es algo que no entiendo, cuando uno de los argumentos que se suele esgrimir es que los derechos de autor son necesarios para la dignidad de los autores. ¿Y qué pintan los descendientes? En realidad los descendientes pintan poco, porque lo que realmente se defiende son las empresas que gestionan y se benefician de esos derechos. Punto.

Las grandes empresas suelen defender sus “derechos” a capa y espada, pero cuando es necesario, no les importa saltarse los derechos de los demás. Hace unos pocos días se publicó Un fotógrafo ‘freelance’ acusa a la agencia EFE de utilizar sin permiso una de sus fotos. La agencia EFE se apropio de forma indebida de una fotografía que se publicó en Twitter. Posteriormente, distribuyo esa fotografía a sus clientes como si fuera suya.

Y en esa misma noticia podemos encontrar un enlace a Multa millonaria para AFP y Getty Images por usar fotos que un fotógrafo publicó en Twitter. Por cierto, hace unos meses un compañero mío recibió una amenazadora carta de Getty Images porque en un sitio web aparecía un icono de su banco de imágenes 🙂

Por último, recomiendo la consultad de «Piratería» de libros y contenidos culturales en España, ronda enésima para ver los cambios de opinión que sufren algunas personas.

Los tuits patrocinados en Twitter

Estoy en Ecuador y la publicidad que recibo en Internet está “adaptada” a esta situación. Por ejemplo, no paro de recibir anuncios sobre el hotel en Quito que reservé a través de Booking. Si ya he estado en un hotel… ¿necesito recibir más publicidad sobre ese hotel? A mí me parece que no.

En Twitter también recibo publicidad a través de los tuits patrocinados. Por ejemplo, me ha sorprendido este para que participe en las próximas elecciones municipales que se celebran en Ecuador y vote al partido del presidente Rafael Correa:

twitter-ecuadorVamos a ver… ¿Twitter no sabe que soy extranjero y que no puedo votar en Ecuador? Lo pone bien claro en mi perfil.

La publicidad en Internet es “selectiva e inteligente”, dicen algunos expertos… ¡y un copón! (expresión típica del sur de Alicante)

 

Mi reino por un enlace

Un seguidor de mi cuenta de Twitter @sergiolujanmora me ha enviado esta noticia: Un simple enlace incorrecto en la web TurisLeon hace perder un dineral a la hostelería leonesa.

La noticia dice:

Si algún turista que pretende visitar la provincia de León quiere buscar un hotel, que no se fíe de la Diputación leonesa ni del Consorcio Provincial de Turismo (TurisLeon), ambos presididos por Isabel Carrasco. Porque la maravillosa herramienta incluida en su web para canalizar esas reservas de hotel, la central de reservas, lleva al menos desde 2011 sin funcionar.

Lo peor del caso es que la absoluta falta de operatividad de esa central de reservas se debe a una nimiedad, algo muy sencillo de subsanar a poco que se preste atención al portal webwww.turisleon.com. Porque el problema radica en que cuando se busca disponibilidad de hoteles por fechas en esa central, automáticamente la página remite supuestamente a la central de reservas de la Junta de Castilla y León, pero con un error en la terminación de la dirección.

Es decir, el turista recibe este mensaje de error porque la web de la Diputación sigue vinculada aesta direccion exacta, que no existe. En realidad, debería vincularse a www.castillayleonesvida.es.

[…]

Esta nueva chapuza de la herramienta turística ‘estrella’ del Patronato, su portal web, se suma a las que iLeon.com destacaba ayer. Tales como que no dispone de traducción al inglés desde su creación en 2009, pese a que se ha ido prometiendo año a año por Carrasco; que estuvo inaccesible durante tres semanas en vísperas de la celebración de Fitur en Madrid; o que no dispone de redes sociales en Facebook, Twitter o ninguna otra para multiplicar la difusión, así como tiene ‘congelado’ su blog.

Internet en el mundo: número de usuarios y su precio

Recientemente, mientras escribía un artículo sobre los MOOCs, he tenido que buscar información sobre el número de usuarios de Internet y el precio o coste de Internet en el mundo.

Por ahí corren algunas estadísticas (Internet, entonces y ahora) que pintan la situación como si todo el mundo estuviese conectado a Internet… y no es así. En el siguiente gráfico se explica un poco mejor la situación:

Global_internet_penetration_in_2012_n

En World Development Indicators: Internet users del Banco Mundial podemos descubrir que hay 10 países en los que el porcentaje de usuarios de Internet es inferior al 2%. Compara eso con los países de la Unión Europea, Estados Unidos o Canadá, en los que el porcentaje está próximo al 90%.

En microsiervos lo resumieron de una forma muy gráfica en No olvidemos que hay dos tipos de personas en el mundo:

usinginternet

Pero el gráfico más detallado lo tenemos en Internet Population and Penetration, que está basado en los datos del Banco Mundial:

InternetPopulation2011_HexCartogram_v7-01

Según estos datos, el 42% de los usuarios de Internet viven en Asia; China, India y Japón por sí solos suman más internautas que Europa y EE UU juntos. Y eso a pesar de que todos los países con más de un 80% de penetración de Internet están en Europa, exceptuando Canadá, Nueva Zelanda, Qatar y Corea del Sur.

Pero a todo esto hay que añadir un dato muy importante: el precio de acceso a Internet. Ahora mismo estoy en Ecuador y he tenido que contratar el servicio de Internet para el apartamento en el que estoy viviendo. He contratado el servicio con la compañía TVCable, el paquete mejorado por $33,49 al mes (25 euros). La velocidad son 4,1 megas (supongo que megabits de descarga quiere decir), pero recibiré como oferta 5,6 durante los primeros 6 meses.

folleto-01

¿Es caro o barato? Si se compara con España, es caro, y si además tenemos en cuenta el nivel de vida, el salario mínimo, ¡¡¡es carísimo!!!

Sólo hay que ver el precio del mejor paquete, el “SMART EXTREMO”, que ofrece 30 megas, por $263,40 al mes. Pero si creo que ONO te ofrece 50 megas por menos de 50 euros. Por tanto, caro no, ¡¡¡carísimo!!! Desgraciadamente, esto es algo que ocurre en muchos países, otro día escribo sobre ello.

En Broadband affordability se recogen datos de 17th edition of the World Telecommunication/ICT Indicators Database de la  International Telecommunication Union (ITU):

Broadband_Affordability

Sorprende descubrir que una conexión a banda ancha cuesta lo mismo, $60, en Australia y Mozambique. Pero hay una diferencia importante: el salario medio anual en Australia son $50.000, mientras que en Mozambique es menos de $500. Esto significa que mientras que en Australia, un persona puede pagar la conexión a Internet de todo un año con lo que gana en una semana, en Mozambique una persona necesita el salario de un año y medio.

Muchas veces, la tecnología aumenta las diferencias…

El cotejamiento, las tablas de MySQL

El cotejamiento un concepto asociado al juego de caracteres y los dos forman parte de los “grandes misterios de la informática”: si se hiciese una encuesta entre un grupo de informáticos, pocos serían los que sabrían contestar con exactitud qué es y para qué sirve el cotejamiento.

Del juego de caracteres he publicado varios artículos y vídeos que se pueden encontrar en este blog en la entrada juego caracteres.

Tengo que hacer algún vídeo sobre el cotejamiento. Hasta que llegue ese momento, dejo aquí un enlace a una página en la que se pueden encontrar las tablas de cotejamiento de varios sistemas gestores de bases de datos, incluyendo MySQL: Collation Charts.

Y un par de capturas de las tablas utf8_spanish:

spanish_collation

y utf8_spanish2:

spanish2_collation

El Tetris en menos de 40 líneas de JavaScript

Impresionante, menos de 40 líneas de JavaScript (y unas cuantas de HTML y CSS). Lo podemos encontrar en esta dirección: http://jsfiddle.net/ova777/kFxja/

Copio a continuación el código por si desaparece:

HTML

<div class=”score”>score: <span id=”result”>0</span></div>

<div id=”stack”>
<div data-y=”0″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”1″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”2″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”3″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”4″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”5″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”6″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”7″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”8″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”9″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”10″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”11″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”12″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”13″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”14″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”15″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”16″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”17″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”18″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
<div data-y=”19″ class=”line”>
<div data-x=”0″ class=”brick”></div><div data-x=”1″ class=”brick”></div><div data-x=”2″ class=”brick”></div><div data-x=”3″ class=”brick”></div><div data-x=”4″ class=”brick”></div><div data-x=”5″ class=”brick”></div><div data-x=”6″ class=”brick”></div><div data-x=”7″ class=”brick”></div><div data-x=”8″ class=”brick”></div><div data-x=”9″ class=”brick”></div>
</div>
</div>

CSS

#stack {
width: 130px;
height: 260px;
border: solid 1px black;
border-top: 0px;
}

.brick {
width: 11px;
height: 11px;
border: solid 1px white;
background: white;
float: left;
}
.brick.on {
background: black;
}
.brick.now {
background: green;
}

JS

var fs = “1111:01|01|01|01*011|110:010|011|001*110|011:001|011|010*111|010:01|11|01:010|111:10|11|10*11|11*010|010|011:111|100:11|01|01:001|111*01|01|11:100|111:11|10|10:111|001″, now = [3,0], pos = [4,0];
var gP = function(x,y) { return document.querySelector(‘[data-y=”‘+y+'”] [data-x=”‘+x+'”]’); };
var draw = function(ch, cls) {
var f = fs.split(‘*’)[now[0]].split(‘:’)[now[1]].split(‘|’).map(function(a){return a.split(”)});
for(var y=0; y<f.length; y++)
for(var x=0; x<f[y].length; x++)
if(f[y][x]==’1′) {
if(x+pos[0]+ch[0]>9||x+pos[0]+ch[0]<0||y+pos[1]+ch[1]>19||gP(x+pos[0]+ch[0],y+pos[1]+ch[1]).classList.contains(‘on’)) return false;
gP(x+pos[0]+ch[0], y+pos[1]+ch[1]).classList.add(cls!==undefined?cls:’now’);
}
pos = [pos[0]+ch[0], pos[1]+ch[1]];
}
var deDraw = function(){ if(document.querySelectorAll(‘.now’).length>0) deDraw(document.querySelector(‘.now’).classList.remove(‘now’)); }
var check = function(){
for(var i=0; i<20; i++)
if(document.querySelectorAll(‘[data-y=”‘+i+'”] .brick.on’).length == 10)
return check(roll(i), document.querySelector(‘#result’).innerHTML=Math.floor(document.querySelector(‘#result’).innerHTML)+10);
};
var roll = function(ln){ if(false !== (document.querySelector(‘[data-y=”‘+ln+'”]’).innerHTML = document.querySelector(‘[data-y=”‘+(ln-1)+'”]’).innerHTML) && ln>1) roll(ln-1); };
window.addEventListener(‘keydown’, kdf = function(e){
if(e.keyCode==38&&false!==(now[1]=((prv=now[1])+1)%fs.split(‘*’)[now[0]].split(‘:’).length) && false===draw([0,0], undefined, deDraw())) draw([0,0],undefined, deDraw(), now=[now[0],prv]);
if((e.keyCode==39||e.keyCode==37)&&false===draw([e.keyCode==39?1:-1,0],undefined,deDraw())) draw([0,0],undefined,deDraw());
if(e.keyCode == 40)
if(false === draw([0,1], undefined, deDraw())) {
if(draw([0,0], ‘on’, deDraw())||true) check();
if(false === draw([0,0], undefined, now = [Math.floor(Math.random()*fs.split(‘*’).length),0], pos = [4,0])) {
toV=-1;
alert(‘Your score: ‘+document.querySelector(‘#result’).innerHTML);
}
}
});
toF = function() {
kdf({keyCode:40});
setTimeout(function(){if(toV>=0)toF();}, toV=toV>0?toV-0.5:toV);
}
toF(toV = 500);

Uso de cookies para mantener la persistencia de un login

A mis alumnos, en la Práctica 9: PHP 2 (cookies y sesiones) les pido que implementen la típica opción de “recordarme” que existe en muchos sitios web. Las cosas que uno ve son muchas veces sorprendentes, pero pocas veces veo algo que realmente sea correcto… el guardar directamente el nombre de usuario y la contraseña en una cookie no es muy seguro 🙂

Sobre este tema no hay mucha información. He intentado averiguar cómo lo hacen sitios web como Google o Facebook, pero no encuentro información sobre ello. ¿Alguien lo sabe?

Lo mejor que he encontrado es el artículo Persistent Login Cookie Best Practice. La solución que propone es fácil de entender e implementar:

The cookie should consist of the user’s username, followed by a separator character, followed by some large random number (128 bits seems mind-bogglingly large enough to be acceptable). The server keeps a table of number->username associations, which is looked up to verify the validity of the cookie. If the cookie supplies a random number and username that are mapped to each other in the table, the login is accepted.

At any time, a username may be mapped to several such numbers. Also, while incredibly unlikely, it does not matter if two usernames are mapped to the same random number.

A persistent cookie is good for a single login. When authentication is confirmed, the random number used to log in is invalidated and a brand new cookie assigned. Standard session-management handles the credentials for the life of the session, so the newly assigned cookie will not be checked until the next session (at which point it, too, will be invalidated after use).

The server need not make the effort of deliberately trying to avoid re-assigning random numbers that have been used before: the chance of it happening is so low that even if it did, nobody would know to make use of it.

When a user logs out through some deliberate logout function, their current cookie number is also invalidated. The user also has an option somewhere to clear all persistent logins being remembered by the system, just in case.

Periodically, the database is purged of associations older than a certain time-period (three months, perhaps: the size of the table would be far more an issue than any possibilities of collision in a 128 bit random space).

The following user functions must not be reachable through a cookie-based login, but only through the typing of a valid password:

  • Changing the user’s password
  • Changing the user’s email address (especially if email-based password recovery is used)
  • Any access to the user’s address, payment details or financial information
  • Any ability to make a purchase