17 votes

Gestion des erreurs non autorisées 401 dans AngularJS

Je suis très novice en AngularJS, et j'ai passé 3 jours à trouver un moyen de gérer le statut 401. J'ai essayé les intercepteurs, l'utilisation de $http, l'utilisation de $resource... mais rien ne fonctionne. Mon application fait un appel JSONP sur le même serveur. Lorsqu'une erreur se produit, elle est prise en compte dans la fonction de rappel d'erreur. mais le statut est toujours 0 et la réponse est indéfinie.

Tout d'abord, j'ai essayé cet intercepteur

app.config(['$httpProvider', function($httpProvider) {
$httpProvider.responseInterceptors.push(['$q', function($q) {
    return function(promise) {
        return promise.then(function(response) {
            console.log('success in interceptor');
            return response; 
        }, function(response) {
            console.log('error in interceptor');
            console.log(response);
            if (response.status === 401) {
                response.data = { 
                    status: false, 
                    description: 'Authentication required!'
                };
                return response;
            }
            return $q.reject(response);
        });
    }
}]);
}]);

Deuxièmement, j'ai également essayé dans les contrôleurs en utilisant $resource

  $scope.fetchData = function(fromDate, toDate){
        Cancel.get({from: fromDate, to: toDate, perPage: 99999},
                    function(data){                            
                      $scope.cancels  = $scope.filteredCancels = data.data;
                      $scope.search();
                    },
                    function(response) {
                      $scope.errorMessage = '<h4>Error : '+response.status+'</h4>';
                      window.location = "/";
                    });              
      }; 

Troisièmement, j'ai essayé d'utiliser $http au lieu de $resource.

  $scope.fetchData = function(fromDate, toDate){
     $http.jsonp('http://host:8900/api/cancellations?callback=JSON_CALLBACK')
         .success(function(data, status, headers, config) {
             console.log(status);
          })
         .error(function(data, status, headers, config) {
             console.log(status);              
          }; 

Voici les informations d'en-tête pour l'appel JSONP

Request URL:http://host:8900/api/cancellations?callback=angular.callbacks._0
Request Method:GET
Status Code:401 Unauthorized
Request Headersview source
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Cache-Control:max-age=0
Connection:keep-alive
Cookie:__utma=149207145.339724205.1374885003.1377550245.1378313049.3; __utmc=149207145; __utmz=149207145.1378313049.3.2.utmcsr=cyphersmart.qc3deva.electricmail.com:8900|utmccn=(referral)|utmcmd=referral|utmcct=/; remember_username=elie.kim%40electricmail.com; PHPSESSID=gdoemlp5jltqq62etc5gfuh653; cookie=cookiecheck; __utma=1.789184132.1378340585.1378499390.1378504453.10; __utmb=1.3.10.1378504453; __utmc=1; __utmz=1.1378340585.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Host:host:8900
Referer:http://host:8900/reports/cancels/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22
Query String Parametersview sourceview URL encoded
callback:angular.callbacks._0
Response Headersview source
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:keep-alive
Content-Type:application/json; charset=utf-8
Date:Fri, 06 Sep 2013 22:02:13 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=20
Pragma:no-cache
Server:nginx/0.7.65
Transfer-Encoding:chunked

Je n'ai pas trouvé de moyen de gérer le statut non autorisé 401, mais j'ai tout mis en place. Je serais très reconnaissant si je pouvais obtenir une astuce ou un conseil aimable.

9voto

Joel Duckworth Points 1327

La réponse acceptée ne fonctionne pas pour les versions ultérieures d'Angular. En utilisant la version 1.5.x (et peut-être même avant), vous devez écrire l'intercepteur différemment :

// http interceptor to handle redirection to login on 401 response from API
app.factory('httpResponseInterceptor', ['$q', '$rootScope', '$location', function($q, $rootScope, $location) {
    return {
        responseError: function(rejection) {
            if (rejection.status === 401) {
                // Something like below:
                $location.path('signin/invalidSession');
            }
            return $q.reject(rejection);
        }
    };
}]);

Postulez avec :

app.config(function($httpProvider) {
    $httpProvider.interceptors.push('httpResponseInterceptor');
});

Voir ici pour plus d'informations https://docs.angularjs.org/api/ng/service/ $http#interceptors

4voto

DrogoNevets Points 459

J'ai eu besoin de faire quelque chose de très similaire récemment, voici mon intercepteur

app.factory("HttpErrorInterceptorModule", ["$q", "$rootScope", "$location",
    function($q, $rootScope, $location) {
        var success = function(response) {
            // pass through
            return response;
        },
            error = function(response) {
                if(response.status === 401) {
                    // dostuff
                }

                return $q.reject(response);
            };

        return function(httpPromise) {
            return httpPromise.then(success, error);
        };
    }
]).config(["$httpProvider",
    function($httpProvider) {
        $httpProvider.responseInterceptors.push("HttpErrorInterceptorModule");
    }
]);

modifié légèrement pour votre cas d'utilisation

3voto

Si un appel à l'API renvoie 401, nous devons rediriger l'utilisateur vers la page de connexion. L'intercepteur HTTP d'Angular est parfait pour cela. Comme vous pouvez le voir dans app.js ci-dessus, il a été poussé vers le pipe ici :

httpProvider.responseInterceptors.push('httpInterceptor');

L'implémentation de l'intercepteur lui-même,

'use strict';

angular.module('dashboardApp').factory('httpInterceptor', function httpInterceptor ($q, $window, $location) {
  return function (promise) {
      var success = function (response) {
          return response;
      };

      var error = function (response) {
          if (response.status === 401) {
              $location.url('/login');
          }

          return $q.reject(response);
      };

      return promise.then(success, error);
  };
});

2voto

Nery Jr Points 1008

Suit une solution similaire ...

angular.module('myApp', ['myApp.services', 'myApp.directives'], function ($routeProvider, $locationProvider, $httpProvider, $location) {

    var httpInterceptor = ['$rootScope', '$q', function (scope, $q) {

        function success(response) {
            return response;
        }

        function error(response) {
            var status = response.status;

            if (status == 401) {
                $location.url('/login');
                return;
            }

            return $q.reject(response);

        }

        return function (promise) {
            return promise.then(success, error);
        }

    }];
    $httpProvider.responseInterceptors.push(httpInterceptor);
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X