ruby-on-rails http utf-8 http-headers

ruby on rails - Caracteres UTF-8 modificados en nombre de usuario de autenticación básica HTTP



ruby-on-rails http-headers (6)

Quiero permitir cualquier carácter UTF-8 válido en los nombres de usuario y contraseñas.

Abandonar toda esperanza. Autenticación básica y Unicode no se mezclan.

No hay un estándar (*) sobre cómo codificar caracteres no ASCII en un nombre de usuario de autenticación básica: token de contraseña antes de basurizarlo. En consecuencia cada navegador hace algo diferente:

  • Opera utiliza UTF-8;
  • IE usa la página de códigos predeterminada del sistema (que no tiene forma de saber, aparte de que nunca es UTF-8), y silencia silenciosamente los caracteres que no encajan usando la adivinación de Windows, un carácter aleatorio que se parece un poco al de Una que querías o tal vez simplemente no ''receta secreta;
  • Mozilla usa solo el byte inferior de los puntos de código de caracteres, lo que tiene el efecto de codificar a ISO-8859-1 y modificar los caracteres que no son 8859-1 de forma irrecuperable ... excepto cuando se realizan las Solicitudes XMLHttp, en cuyo caso utiliza UTF-8;
  • Safari y Chrome codifican a ISO-8859-1, y no pueden enviar el encabezado de autorización en absoluto cuando se utiliza un carácter que no sea 8859-1.

*: algunas personas interpretan el estándar para decir que:

  • debe ser siempre ISO-8859-1, debido a que es la codificación predeterminada para incluir caracteres en bruto de 8 bits directamente incluidos en los encabezados;
  • debería estar codificado usando las reglas RFC2047, de alguna manera.

Pero ninguna de estas propuestas está en el tema para su inclusión en un token de autenticación codificado en base64, y la referencia RFC2047 en la especificación HTTP realmente no funciona en absoluto, ya que todos los lugares en los que podría estar potencialmente utilizados están explícitamente rechazados por el ''contexto atómico Las reglas de RFC2047 en sí, incluso si los encabezados HTTP cumplen las reglas y extensiones de la familia RFC822, no lo hacen.

En resumen: ugh. Hay pocas esperanzas de que esto se solucione en el estándar o en los navegadores que no sean Opera. Es solo un factor más que aleja a las personas de la autenticación básica HTTP en lugar de esquemas de autenticación no estándar y menos accesibles basados ​​en cookies. Vergüenza de verdad.

Estoy tratando de construir un servicio web usando Ruby on Rails. Los usuarios se autentican a través de HTTP Basic Auth. Quiero permitir cualquier carácter UTF-8 válido en los nombres de usuario y contraseñas.

El problema es que el navegador está modificando los caracteres en las credenciales de Autenticación básica antes de enviarlos a mi servicio. Para las pruebas, estoy usando ''カ タ カ ナ

Si yo tomo como una cadena y hacer username.unpack ( "h *") para convertirlo en hexadecimal, me sale: ''3e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a8'' Eso parece bastante bien por 32 caracteres kanji (3 bytes / 6 dígitos hexadecimales por).

Si hago lo mismo con el nombre de usuario que viene a través de la autenticación HTTP básica, obtengo: ''bafbbaacbafbbaacbafbbaacbafbbaacbafbbaacbafbbaacbafbbaacbafbbaac''. Obviamente es mucho más corto. Usando el complemento Encabezados HTTP de Firefox Live, aquí está el encabezado real que se está enviando:

Authorization: Basic q7+ryqu/q8qrv6vKq7+ryqu/q8qrv6vKq7+ryqu/q8o6q7+ryqu/q8qrv6vKq7+ryqu/q8qrv6vKq7+ryqu/q8o=

Se parece a esa cadena ''bafbba ...'', con los bocetos altos y bajos intercambiados (al menos cuando los pego en Emacs, descodificación de base 64, luego cambio al modo hexl). Esa podría ser una representación UTF16 del nombre de usuario, pero no he conseguido nada que lo muestre como algo más que tonterías.

Rails está configurando el encabezado de tipo de contenido en UTF-8, por lo que el navegador debería enviar esa codificación. Obtengo los datos correctos para las presentaciones de formularios.

El problema ocurre tanto en Firefox 3.0.8 como en IE 7.

Entonces ... ¿hay alguna salsa mágica para que los navegadores web envíen caracteres UTF-8 a través de la autenticación básica HTTP? ¿Estoy manejando las cosas mal en el extremo receptor? ¿HTTP Basic Auth simplemente no funciona con caracteres que no son ASCII?


¿Has probado usar algo como curl para asegurarte de que no sea un problema de Firefox? HTTP Auth RFC no dice nada sobre ASCII en comparación con no ASCII, pero sí dice que el valor pasado en el encabezado es el nombre de usuario y la contraseña separados por dos puntos, y no puedo encontrar dos puntos en la cadena que Firefox informa enviando.


Es un defecto conocido que la autenticación básica no proporciona soporte para caracteres que no sean ISO-8859-1.

Se sabe que algunos UAs usan UTF-8 en su lugar (Opera viene a la mente), pero tampoco existe interoperabilidad para eso.

Por lo que puedo decir, no hay manera de solucionar esto, excepto definiendo un nuevo esquema de autenticación que maneje todos los Unicode. Y conseguirlo desplegado.


La autenticación HTTP Digest tampoco es una solución para este problema. Tiene el mismo problema de que el cliente no puede decirle al servidor qué conjunto de caracteres está usando y el servidor no puede asumir correctamente lo que usó el cliente.


Puede que sea un ignorante total, pero llegué a esta publicación mientras buscaba un problema mientras enviaba una cadena UTF8 como encabezado dentro de una llamada ajax.

Podría resolver mi problema codificando en la cadena Base64 justo antes de enviarlo. Eso significa que con JS simple podría convertir el formulario a base64 justo antes de enviarlo, y de esa manera puede volver a ejecutarse en el lado del servidor.

Estas herramientas simples me permitieron que se enviaran cadenas utf8 como ASCII simple. Encontré que gracias a esta simple frase:

base64 (esta codificación está diseñada para que los datos binarios sobrevivan al transporte a través de las capas de transporte que no están limpias en 8 bits). http://www.webtoolkit.info/javascript-base64.html

Espero que esto ayude de alguna manera. ¡Solo tratando de devolver un poco a la comunidad!