$http Auth Headers in AngularJS

You're mixing the use cases; instantiated services ($http) cannot be used in the config phase, while providers won't work in run blocks. From the module docs:

  • Configuration blocks - […] Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.
  • Run blocks - […] Only instances and constants can be injected into run blocks. This is to prevent further system configuration during application run time.

So use either of the following:

app.run(['$http', function($http) {
    $http.defaults.headers.common['Authorization'] = /* ... */;
}]);
app.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.headers.common['Authorization'] = /* ... */;
}])

I have a service factory that has an angular request interceptor like so:

var module =  angular.module('MyAuthServices', ['ngResource']);

module
    .factory('MyAuth', function () {
    return {
        accessTokenId: null
    };
})    
.config(function ($httpProvider) {
    $httpProvider.interceptors.push('MyAuthRequestInterceptor');
})

.factory('MyAuthRequestInterceptor', [ '$q', '$location', 'MyAuth',
    function ($q, $location, MyAuth) {
        return {
            'request': function (config) {


                if (sessionStorage.getItem('accessToken')) {

                    console.log("token["+window.localStorage.getItem('accessToken')+"], config.headers: ", config.headers);
                    config.headers.authorization = sessionStorage.getItem('accessToken');
                }
                return config || $q.when(config);
            }
            ,
            responseError: function(rejection) {

                console.log("Found responseError: ", rejection);
                if (rejection.status == 401) {

                    console.log("Access denied (error 401), please login again");
                    //$location.nextAfterLogin = $location.path();
                    $location.path('/init/login');
                }
                return $q.reject(rejection);
            }
        }
    }]);

Then on logging in in my login controller I store the accesstoken using this line:

sessionStorage.setItem('currentUserId', $scope.loginResult.user.id);
sessionStorage.setItem('accessToken', $scope.loginResult.id);
sessionStorage.setItem('user', JSON.stringify($scope.loginResult.user));
sessionStorage.setItem('userRoles', JSON.stringify($scope.loginResult.roles));

This way I can assign the headers to the request on every request made after I log in. This is just the way I do it, and is totally up for criticism, but it appears to work very well.


You can use it in the controller:

.controller('Controller Name', ['$http', function($http) {
   $http.defaults.headers.common['Authorization'] = 'Basic ' + login + ':' + password;
}]);

In the angularjs documentation you can see some ways to set headers but I think this is what you are searching:

$http({
    method: 'POST',
    url: '/theUrl',
    headers: {
        'Authorization': 'Bearer ' + 'token'
         //or
         //'Authorization': 'Basic ' + 'token'
    },
    data: someData
}).then(function successCallback(response) {
    $log.log("OK")
}, function errorCallback(response) {
    if(response.status = 401){ // If you have set 401
        $log.log("ohohoh")
    }
});

I'm using this structure in my angularjs client with an ASP.NET 5 server and it works.