0

Zuerst hatte ich configAuth mit Headern, einschließlich JWT-Token bei jedem Controller.Wie Interceptor für verschiedene Anfragen (URLs) zu spalten?

Aber jetzt, wenn ich eine große Anzahl von Controllern habe, merkte ich, dass ich etwas dagegen tun muss. Ich habe von interceptors gehört und versucht, sie zu bekommen.

Ich weiß, dass ich Token nicht einfach jeder Anfrage stellen kann, denn es gibt einige Seiten und Anfragen wie /login, die überhaupt kein Token Authorization haben sollten. Und das Erhalten von HTML-Dateien mit Authorization header gibt mir irgendwie eine Ausnahme. Also habe ich versucht, Anfragen so zu spalten:

angular.module('App') 

.factory('sessionInjector',['$injector', function ($injector) { 
    var sessionInjector = { 
     request: function (config) { 
      if (config.url == "/one" || config.url == "/two"){ 
       config.headers['Content-Type'] = 'application/json;charset=utf-8;'; 
       config.headers['Authorization'] = localStorage.getItem('token'); 
      } else { 
       config.headers['Content-Type'] = 'application/json;charset=utf-8;'; 
      } 
      return config; 
     }, 
     response: function(response) { 
      if (response.status === 401) { 
       var stateService = $injector.get('$state'); 
       stateService.go('login'); 
      } 
      return response || $q.when(response); 
     } 
    }; 
    return sessionInjector; 
}]); 

Aber es funktioniert nicht mit Anfragen wie /one/{one_id} und ich kann alle Möglichkeiten nicht hart codieren. Was ist die beste Vorgehensweise dafür?

+0

Nicht hier in den besten Praktiken gehen, aber Sie können leicht flexibler Matcher verwenden als ' config.url == "/ eins" '. Zum Beispiel können Sie überprüfen, ob die URL * mit "/ one" beginnt, indem Sie 'config.url.indexOf ('/ one') === 0' oder mit Regex verwenden. Wenn Sie mehr Routen benötigen, die eine Autorisierung benötigen, als diejenigen, die nicht autorisiert sind, können Sie die Prüfung auch anders herum durchführen, wie zum Beispiel 'if (config.url! == '/ login')'. – noppa

Antwort

1

Was Sie jetzt haben, ist ein guter Ausgangspunkt. Ich gehe davon aus, dass die meisten Ihrer APIs das Authentifizierungs-Token benötigen. Das Einrichten der Endpunkte, die keine Authentifizierung erfordern, wäre wahrscheinlich der schnellere Pfad. Ich habe das nicht getestet, aber es könnte Sie auf den richtigen Weg bringen. Ich habe Ihren Injektor als Provider eingerichtet, damit Sie die anonymen Routenregeln in der Konfiguration konfigurieren können.

angular.module('App') 
    .provider('sessionInjector',[function() { 
     var _anonymousRouteRules; 

     this.$get = ['$injector', getSessionInjector]; 
     this.setupAnonymousRouteRules = setupAnonymousRouteRules; 

     function getSessionInjector($injector) { 
      var service = { 
       request: requestTransform, 
       response: responseTransform 
      }; 

      function requestTransform(config) {   
       if (!isAnonymousRoute(config.url)){ 
        config.headers['Authorization'] = localStorage.getItem('token'); 
       } 

       config.headers['Content-Type'] = 'application/json;charset=utf-8;'; 

       return config; 
      } 

      function responseTransform(response) { 
       if (response.status === 401) { 
        var stateService = $injector.get('$state'); 
        stateService.go('login'); 
       } 
       return response || $q.when(response); 
      } 

      return service; 
     } 

     function isAnonymousRoute(url) { 
      var isAnonymous = false; 
      angular.forEach(_anonymousRouteRules, function(rule) { 
       if(rule.test(url)) { 
        isAnonymous = true; 
       } 
      }); 
      return isAnonymous; 
     } 

     function setupAnonymousRouteRules(anonymousRouteRules) { 
      _anonymousRouteRules = anonymousRouteRules; 
     } 
    }]); 

Damit können Sie die Regeln, indem man in einer Reihe von regulären Ausdrücken für Ihre URLs konfigurieren:

angular.module('App').config(['sessionInjectorProvider', config]); 

function config(sessionInjectorProvider) { 
    sessionInjectorProvider.setupAnonymousRouteRules([ 
     /.*\.html$/, 
     /^\/login$/ 
    ]); 
} 
1

Es gibt einen besseren Weg, dies zu tun. Setzen Sie nach der Anmeldung das Authentifizierungs-Token in die Kopfzeile des $ http-Dienstes. Damit müssen Sie das Konfigurationsobjekt nicht bei jedem Aufruf übergeben.

Anmeldung:

function Login(credentials){ 
    $http.post(apiPath, credentials).then(function (data) { 
     $http.defaults.headers.common['Authorization'] = data['token']; 
    }); 
} 

Alle HTTP-Aufrufe danach wird Authorization-Header gesetzt haben.

Es gibt jedoch einige Aufrufe, die keine Autorisierung erfordern. In diesen Fällen können Sie eine Funktion schreiben, deren eigenes Konfigurationsobjekt ohne Autorisierung in der Kopfzeile übergeben wurde.

Funktion ohne Berechtigung:

function Without_Auth(url, data) { 
    var deferred = $q.defer(); 
    var responsePromise = $http({ 
     method: 'post', 
     url: url, 
     data: data, 
     headers: { 
      'Content-Type': 'application/json;charset=utf-8;' 
     } 
    }) 
    responsePromise.success(function (data) { 
     deferred.resolve(data); 
    }); 
    responsePromise.error(function (err) { 
     deferred.reject(); 
    }); 
    return deferred.promise; 
} 

Hope this löst Ihr Problem!