Search code examples
angularjsresthttp-headersngresourceangularjs-rootscope

Broadcast headers to all resources after calling another one resource


I built a rest api, now it's time to handle data with angular. To do that, I built a service to make a connection to my resources.

So I've :

angular.module("myServiceRest", ['ngResource'])

.factory("myService",  function ($rootScope, $resource) {



    var apiData = $resource(
        "/api", {},
        {
            "getContains": {method: 'GET', isArray: false, url: "/api/users/:userid/:yearid/:groupeid/:levelid", headers: $rootScope.headers},
            "getContain": {method: 'GET', isArray: false, url: "/api/Contains/:containid", headers: $rootScope.headers},

            "postAuthTokens": {method: 'POST', url: "/api/auth-tokens"}

        });

    return {
        getGroupesContenus: function (user_id, year_id, groupe_id, level_id) {
            return apiData.getContains({userid: user_id, yearid: year_id, groupeid: groupe_id, levelid: level_id});
        },
        getContain: function (contain_id) {
            return apiData.getContain({containid: contain_id});
        },

        postAuthTokens: function(userData) {
            apiData.postAuthTokens(userData, function (data) {
                console.log("success !");
                $rootScope.headers = {
                    "Content-Type": "application/json",
                    "Authorization": "Basic ZWRnYXJrYW1kZW06TkVXVE9O",
                    "Accept": "application/json",
                    "X-Auth-Token": data.value
                };
            }, function (error) {
                console.log(error.data);
            })

        }
    }
});

Here I have 3 resources :

  • getContains: /api/users/:userid/:yearid/:groupeid/:levelid
  • getContain: /api/Contains/:containid
  • postAuthTokens: /api/auth-tokens

To get access to getContains and getContain (after logged in), the user need to set a token (X-Auth-Token) retrieved through postAuthTokens.

Basically, when the user log in, he calls the POST resource postAuthTokens, and retrieve his token (stored in a database) through data.value, and have to set that token in X-Auth-Token in order to continue.

For that, I created a $rootScope, and immediately when the user get log in, I set :

$rootScope.headers = {
                "Content-Type": "application/json",
                "Authorization": "Basic ZWRnYXJrYW1kZW06TkVXVE9O",
                "Accept": "application/json",
                "X-Auth-Token": data.value //Set the user token
            };

But it doesn't work at all. It's like $rootScope.headers got reinitialize after calling post Auth Tokens, because, when the user log in I got this error in my Chrome console afterward:

angular.js:14328 Possibly unhandled rejection: {"data":{"error":{"code":500,"message":"Internal Server Error","exception":[{"message":"X-Auth-Token header is required","class":"Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException","trace":...

My $rootScope.headers wasn't set at all.

So how can I broadcast my $rootScope.headers to all resource headers after calling postAuthTokens ?


Solution

  • Instead of adding the headers to the root scope, add them to the $http service:

    $http.defaults.headers.common['X-Auth-Token'] = data.value

    They should then be added to all subsequent HTTP requests automatically