Reputation: 862
At first I've had configAuth
with headers, including JWT token at every Controller.
var configAuth = {
headers: {
'Content-Type': 'application/json',
'Authorization': localStorage.getItem('token')
}
};
But now when I have great ammount of Controllers, I realized that I need to do something about it. I've heard about interceptors
and trying to get them.
I know that I can't just put token to every request, because there's some pages and requests like /login
that shouldn't have Authorization
token at all. And getting html files with Authorization header
is somehow giving me an exception. So I've tried to split requests like that:
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;
}]);
But it doesn't work with requests like /one/{one_id}
and I can't hardcode all the possibilities. So what is the best practice for this?
Upvotes: 0
Views: 341
Reputation: 1349
What you have now is a good starting point. I'm assuming the majority of your APIs will need the auth token, so setting up which endpoints don't require auth would probably be the quicker path. I haven't tested this, but it might get you on the right track. I setup your injector as a provider so you can configure the anonymous route rules within the config.
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;
}
}]);
With this, you can configure the rules by passing in an array of regexes for your urls:
angular.module('App').config(['sessionInjectorProvider', config]);
function config(sessionInjectorProvider) {
sessionInjectorProvider.setupAnonymousRouteRules([
/.*\.html$/,
/^\/login$/
]);
}
Upvotes: 1
Reputation: 121
There is a better way of doing this. After login in set the auth token into the header of $http service. So that you don't need to pass the config object in each call.
Login :
function Login(credentials){
$http.post(apiPath, credentials).then(function (data) {
$http.defaults.headers.common['Authorization'] = data['token'];
});
}
All the HTTP calls after this will have Authorization header set.
But there are some call which doesn't require Authorization in those cases you can write a function which have its own config object passed without Authorization in the header.
Function without Authorization:
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 solves your problem!
Upvotes: 1