simple node basada autenticación autenticacion javascript ajax angularjs http authentication

javascript - node - token de autenticación



Evitar el cuadro de diálogo de autenticación básica de HTTP utilizando interceptores AngularJS (3)

¡Lo averigué!

El truco consistía en enviar un encabezado de respuesta WWW-Authenticate de algún valor distinto de Basic . Luego puede capturar el 401 con un interceptor $http básico, o algo aún más inteligente como angular-http-auth .

Estoy construyendo una aplicación web AngularJS (1.2.16) con una API RESTful, y me gustaría enviar 401 respuestas no autorizadas para las solicitudes donde la información de autenticación no es válida o no está presente. Cuando lo hago, incluso con un interceptor HTTP presente, veo que el navegador presenta el diálogo básico "Autenticación requerida" cuando se realiza una solicitud AJAX a través de AngularJS. Mi interceptor se ejecuta después de ese diálogo, que es demasiado tarde para hacer algo útil.

Un ejemplo concreto:

Mi API backend devuelve 401 para /api/things menos /api/things haya un token de autorización presente. Agradable y simple.

En el lado de la aplicación AngularJS, miré los docs y configuré un interceptor como este en el bloque de config :

$httpProvider.interceptors.push([''$q'', function ($q) { return { ''responseError'': function (rejection) { if (rejection.status === 401) { console.log(''Got a 401'') } return $q.reject(rejection) } } }])

Cuando cargo mi aplicación, elimino el token de autenticación y realizo una llamada AJAX a /api/things (para poder activar el interceptor anterior), veo esto:

Si cancelo ese diálogo, veo la salida console.log de "Got a 401" que esperaba ver en lugar de ese diálogo :

Claramente, el interceptor está funcionando, pero está interceptando demasiado tarde.

Veo numerosos mensajes en la web sobre autenticación con AngularJS en situaciones como esta, y todos parecen usar interceptores HTTP, pero ninguno menciona el diálogo de autenticación básica apareciendo. Algunos pensamientos erróneos que tuve para su apariencia incluyen:

  • Falta Content-Type: application/json cabecera de la Content-Type: application/json en la respuesta? No, está ahí.
  • ¿Necesita devolver algo que no sea el rechazo de promesa? Ese código siempre se ejecuta después del diálogo, sin importar qué se devuelva.

¿Me falta algún paso de configuración o el uso incorrecto del interceptor?


Tuve este problema junto con Spring Boot Security (HTTP básico) y, desde Angular 1.3, debe establecer $httpProvider.defaults.headers.common["X-Requested-With"] = ''XMLHttpRequest''; para que la ventana emergente no aparezca.


Para futura referencia

He encontrado esta solución al tratar de manejar los errores 401 . No tuve la opción de reescribir Basic to x-Basic o algo similar, así que decidí manejarlo en el lado del cliente con Angular.

Al iniciar un cierre de sesión, primero intente hacer una mala solicitud con un usuario falso para descartar las credenciales actualmente en caché.

Tengo esta función haciendo las solicitudes (está usando $.ajax jquery con llamadas asynch deshabilitadas):

function authenticateUser(username, hash) { var result = false; var encoded = btoa(username + '':'' + hash); $.ajax({ type: "POST", beforeSend: function (request) { request.setRequestHeader("Authorization", ''Basic '' + encoded); }, url: "user/current", statusCode: { 401: function () { result = false; }, 200: function (response) { result = response; } }, async: false }); return result; }

Entonces, cuando trato de desconectar a un usuario, sucede esto:

//This will send a request with a non-existant user. //The purpose is to overwrite the cached data with something else accountServices.authenticateUser(''logout'',''logout''); //Since setting headers.common.Authorization = '''' will still send some //kind of auth data, I''ve redefined the headers.common object to get //rid of the Authorization property $http.defaults.headers.common = {Accept: "application/json, text/plain, */*"};