0

Сначала у меня был configAuth с заголовками, включая токен JWT на каждом контроллере.Как разбить перехватчик для разных запросов (URL)?

var configAuth = { 
    headers: { 
     'Content-Type': 'application/json', 
     'Authorization': localStorage.getItem('token') 
    } 
}; 

Но теперь, когда у меня есть большое количество контроллеров, я понял, что мне нужно что-то сделать. Я слышал о interceptors и пытался их получить.

Я знаю, что я не могу просто поставить токен на каждый запрос, потому что есть некоторые страницы и запросы, такие как /login, которые не должны иметь токен Authorization. И получение html-файлов с Authorization header каким-то образом дает мне исключение. Так что я пытался разделить запросы так:

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; 
}]); 

Но она не работает с запросами, как /one/{one_id} и я не могу жёстко все возможности. Итак, какова наилучшая практика для этого?

+0

Не вдаваясь в лучшие практики, но вы можете легко использовать более гибкие matchers, чем ' config.url == "/ one" '. Например, вы можете проверить, запускается ли url * с помощью «/ one» с помощью 'config.url.indexOf ('/ one') === 0' или с регулярным выражением. Кроме того, если у вас больше маршрутов, требующих авторизации, чем у вас нет, вы можете повернуть проверку другим способом, например 'if (config.url! == '/ login')'. – noppa

ответ

1

У вас сейчас хорошая отправная точка. Я предполагаю, что большинству ваших API потребуется токен auth, поэтому настройка конечных точек не требует auth, вероятно, будет более быстрым путем. Я не тестировал это, но это может привести вас к правильному пути. Я устанавливаю ваш инжектор в качестве поставщика, поэтому вы можете настроить правила анонимного маршрута в конфигурации.

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; 
     } 
    }]); 

При этом, вы можете настроить правила, передавая массив регулярных выражений для URLs:

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

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

Существует лучший способ сделать это. После входа в систему установите токен аутентификации в заголовок $ http service. Так что вам не нужно передавать объект конфигурации в каждом вызове.

Логин:

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

Все HTTP вызовы после этого будет иметь набор заголовков авторизации.

Но есть некоторый вызов, который не требует авторизации. В этих случаях вы можете написать функцию, которая имеет свой собственный объект конфигурации, переданный без авторизации в заголовке.

Функция без авторизации:

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; 
} 

Надеется, что это решит вашу проблему!

Смежные вопросы