Dónde guardar un JWT en una aplicación basada en navegador y cómo usarlo
Estoy tratando de implementar JWT en mi sistema de autenticación y tengo algunas preguntas. Para almacenar el token, podría usar cookies, pero también es posible usar localStorage
o sessionStorage
.
¿Cuál sería la mejor opción?
He leído que JWT protege el sitio de CSRF. Sin embargo, no puedo imaginar cómo funcionaría suponiendo que guarde el token JWT en el almacenamiento de cookies.
¿Cómo protegería entonces de la CSRF?
Actualización 1
Vi algunas muestras de uso como el siguiente:
curl -v -X POST -H "Authorization: Basic VE01enNFem9FZG9NRERjVEJjbXRBcWJGdTBFYTpYUU9URExINlBBOHJvUHJfSktrTHhUSTNseGNh"
¿Cómo puedo implementar eso cuando hago una solicitud al servidor desde el navegador? También vi que algunos implementan el token en la URL:
http://exmple.com?jwt=token
Si hiciera una solicitud a través de AJAX, entonces podría establecer un encabezado como jwt: [token]
y luego podría leer el token desde el encabezado.
Actualización 2
Instalé la extensión avanzada del cliente REST de Google Chrome y pude pasar el token como un encabezado personalizado. ¿Es posible establecer estos datos de encabezado a través de Javascript al hacer una solicitud GET al servidor?
3 answers
Mira este sitio web: https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token /
Si desea almacenarlos, debe usar localStorage o sessionStorage si está disponible o cookies. También debe usar el encabezado Authorization, pero en lugar del esquema Básico, use el Portador:
curl -v -X POST -H "Authorization: Bearer YOUR_JWT_HERE"
Con JS, puedes usar el siguiente código:
<script type='text/javascript'>
// define vars
var url = 'https://...';
// ajax call
$.ajax({
url: url,
dataType : 'jsonp',
beforeSend : function(xhr) {
// set header if JWT is set
if ($window.sessionStorage.token) {
xhr.setRequestHeader("Authorization", "Bearer " + $window.sessionStorage.token);
}
},
error : function() {
// error handler
},
success: function(data) {
// success handler
}
});
</script>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-27 00:07:05
Elegir el almacenamiento es más acerca de las compensaciones que tratar de encontrar una mejor opción definitiva. Veamos algunas opciones:
Opción 1-Almacenamiento web (localStorage
o sessionStorage
)
Pros
- El navegador no incluirá automáticamente nada del almacenamiento Web en las solicitudes HTTP, lo que lo hace no vulnerable a CSRF
- Solo se puede acceder mediante Javascript que se ejecuta en el mismo dominio exacto que creó los datos
- Permite utilizar la mayoría enfoque semánticamente correcto para pasar credenciales de autenticación de tokens en HTTP (el encabezado
Authorization
con un esquemaBearer
) - Es muy fácil seleccionar las solicitudes que deben contener autenticación
Cons
- No se puede acceder mediante Javascript que se ejecuta en un subdominio del que creó los datos (un valor escrito por
example.com
no se puede leer porsub.example.com
) - ⚠️ Es vulnerable a XSS
- Para realizar solicitudes autenticadas, solo puede use API de navegador / biblioteca que le permitan personalizar la solicitud (pase el token en el encabezado
Authorization
)
Uso
Aprovechar el navegador localStorage
o sessionStorage
API para almacenar y luego recuperar el token al realizar las solicitudes.
localStorage.setItem('token', 'asY-x34SfYPk'); // write
console.log(localStorage.getItem('token')); // read
Opción 2-Cookie de solo HTTP
Pros
- Es no vulnerable a XSS
- El navegador incluye automáticamente el token en cualquier solicitud que cumpla con la cookie especificación (dominio, ruta y vida útil)
- La cookie se puede crear en un dominio de nivel superior y se puede utilizar en solicitudes realizadas por subdominios
Cons
- }️ Es vulnerable a CSRF
- Debe ser consciente y tener siempre en cuenta el posible uso de las cookies en los subdominios
- Seleccionar las solicitudes que deben incluir la cookie es factible, pero messier
- Es posible que (todavía) tenga algunos problemas con pequeñas diferencias en la forma en que los navegadores tratamiento de las cookies
- }️ Si no tienes cuidado, puedes implementar una estrategia de mitigación de CSRF que sea vulnerable a XSS
- El lado del servidor necesita validar una cookie para la autenticación en lugar del encabezado
Authorization
más apropiado
Uso
No necesita hacer nada del lado del cliente, ya que el navegador se encargará automáticamente de las cosas por usted.
Opción 3-Cookie accesible de Javascript ignorada por lado del servidor
Pros
- Es no vulnerables a CSRF (porque es ignorado por el servidor)
- La cookie se puede crear en un dominio de nivel superior y se puede utilizar en solicitudes realizadas por subdominios
- Permite utilizar el enfoque semánticamente correcto para pasar credenciales de autenticación de token en HTTP (el encabezado
Authorization
con un esquemaBearer
) - Es algo fácil seleccionar las solicitudes que deben contener autenticación
Cons
- }️ Es vulnerable a XSS
- Si no tiene cuidado con la ruta donde establece la cookie, el navegador la incluye automáticamente en las solicitudes, lo que agregará una sobrecarga innecesaria
- Para realizar solicitudes autenticadas, solo puede usar API de navegador / biblioteca que le permitan personalizar la solicitud (pase el token en el encabezado
Authorization
)
Uso
Usted aprovecha la navegador document.cookie
API para almacenar y luego recuperar el token al realizar solicitudes. Esta API no es tan fina como el almacenamiento web (obtienes todas las cookies), por lo que necesitas trabajo adicional para analizar la información que necesitas.
document.cookie = "token=asY-x34SfYPk"; // write
console.log(document.cookie); // read
Notas adicionales
Esto puede parecer una opción extraña, pero tiene la buena ventaja de que puede tener almacenamiento disponible para un dominio de nivel superior y todos los subdominios, que es algo que el almacenamiento web no le dará. Sin embargo, es más complejo implementar.
Conclusión-Notas finales
Mi recomendación para los escenarios más comunes sería ir con la opción 1, principalmente porque:
- Si crea una aplicación Web, debe tratar con XSS; siempre, independientemente de dónde almacene sus tokens
- Si no utiliza la autenticación basada en cookies, el CSRF ni siquiera debería aparecer en su radar, por lo que es una cosa menos de la que preocuparse
También tenga en cuenta que la cookie basada las opciones también son bastante diferentes, para la Opción 3 las cookies se utilizan puramente como un mecanismo de almacenamiento, por lo que es casi como si fuera un detalle de implementación del lado del cliente. Sin embargo, la opción 2 significa una forma más tradicional de tratar con la autenticación; para leer más sobre esto cookies vs token, puede encontrar este artículo interesante: Cookies vs Tokens: La Guía Definitiva.
Finalmente, ninguna de las opciones lo menciona, pero el uso de HTTPS es obligatorio, por supuesto, lo que haría significa que las cookies deben crearse adecuadamente para tener esto en cuenta.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-02 10:42:53
Esta entrada de blog tiene una excelente comparación lado a lado del almacenamiento del navegador frente a las cookies y aborda cada ataque potencial en cada caso. https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage /
La respuesta / spoiler más corto: cookies y añadir token xsrf en el jwt. Explicación detallada en la entrada del blog.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-19 07:26:07