I am building a project in ionic and I need to send jwt tokens with each request. I am a total angular newbie and I wonder where I need to place the logic for http interceptors. Where should I do that, should I put that inside config part, make a new service or something else?
This is the interceptor logic I need to insert:
$httpProvider.interceptors.push(['$q', '$location', '$localStorage', function ($q, $location, $localStorage) {
return {
'request': function (config) {
config.headers = config.headers || {};
if ($localStorage.token) {
config.headers.Authorization = 'Bearer ' + $localStorage.token;
}
return config;
},
'responseError': function (response) {
if (response.status === 401 || response.status === 403) {
$location.path('/signin');
}
return $q.reject(response);
}
};
}]);
This is the config part in my app.js:
.config(function($stateProvider, $urlRouterProvider, $authProvider, ApiEndpoint) {
$authProvider.loginUrl = ApiEndpoint.url + '/authenticate';
$stateProvider
.state('main', {
url: '/main',
abstract: true,
templateUrl: 'templates/main.html'
})
.state('main.auth', {
url: '/auth',
views: {
'content': {
templateUrl: 'templates/login.html',
controller: 'AuthController'
}
}
})
.state('main.front', {
url: '/front',
views: {
'content': {
templateUrl: 'templates/main-front.html',
controller: 'FrontPageController'
}
}
})
.state('main.article', {
url: '/article/{id}',
views: {
'content': {
templateUrl: 'templates/main-article.html',
controller: 'ArticleController'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/main/front');
});
I have added it to services.js like this, I wonder if this is the right approach?
Updated code
services.js
angular.module('coop.services', [])
.factory('ArticleService', function($http, ApiEndpoint) {
return {
all: function() {
return $http.get(ApiEndpoint.url + "/articles/latest").then(function(response){
articles = response.data;
return articles;
});
},
get: function(id) {
return this.all().then(function(response) {
var articles = response;
for (var i in articles) {
if (articles[i].id == id) {
return articles[i];
}
}
return {};
})
}
};
})
.factory('AuthenticationInterceptor', function RequestInterceptor($q, $location, $localStorage, $rootScope, CoreConfig) {
var service = this;
service.request = function (config) {
config.headers = config.headers || {};
if ($localStorage.token) {
config.headers.Authorization = 'Bearer ' + $localStorage.token;
}
return config;
};
service.responseError = function (response) {
if (response.status === 401 || response.status === 403) {
$location.path('/signin');
}
return $q.reject(response);
};
return service;
});
.config part in app.js:
.config(function($stateProvider, $urlRouterProvider, $authProvider, ApiEndpoint, $httpProvider) {
$httpProvider.interceptors.push('AuthenticationInterceptor');
$authProvider.loginUrl = ApiEndpoint.url + '/authenticate';
$stateProvider
.state('main', {
url: '/main',
abstract: true,
templateUrl: 'templates/main.html'
})
.state('main.auth', {
url: '/auth',
views: {
'content': {
templateUrl: 'templates/login.html',
controller: 'AuthController'
}
}
})
.state('main.front', {
url: '/front',
views: {
'content': {
templateUrl: 'templates/main-front.html',
controller: 'FrontPageController'
}
}
})
.state('main.article', {
url: '/article/{id}',
views: {
'content': {
templateUrl: 'templates/main-article.html',
controller: 'ArticleController'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/main/front');
});
The Interceptors are usually configured at the bootstrapping phase.
I tend to handle it under the app config:
"An interceptor is simply a factory() service that returns an object with 4 properties that map to functions". So write your interceptor as a normal service with which methods you need overide (request, response, requestError, responseError).
In code example below, I just care to request and respondError property so I just return a service with two propertis. You can also made many interceptors to handle each kind of these property. Many interceptors can be applied to only one property (some kind of interceptor: authentication, handle error, restore request, pre-process response/request data...).
then push your interceptor at config phase: