1
votes

I need to use web tokens for authentication and to access my REST API. I am also trying to access a weather API, but cannot access it because the headers are sending a x-access-token and I am getting this error:

Request header field x-access-token is not allowed by Access-Control-Allow-Headers.

I've tried the following to reset the headers token to undefined for that particular request. Unfortunately when I inspect the config object in the browser console the user's token is still there. Please help!

weatherService.js

//Make a request to GET weather by zip code
    weatherFactory.getWeather = function(zip){
      $http.get('http://api.openweathermap.org/data/2.5/forecast/city?id=524901',
                {
                  headers: {'x-access-token': undefined}
                })
        //Resolve our promise with the data requested
        .success(function(data){
          console.log(data);
        })
        //Promise will be rejected
        .error(function(err){
          console.log('Error getting data');
        });
        return $q.reject(zip);
    };//end getWeather

app.js

//./public/app/app.js
angular.module('swellsApp', [
  // 'ngAnimate',
  'appRoutes',
  'userService',
  'weatherService',
  'mainCtrl',
  'userCtrl',
  'weatherCtrl'
])
  //application configuration to integrate tokens into our requests
  .config(function($httpProvider){
    //attach auth interceptor to the http requests
    $httpProvider.interceptors.push('AuthInterceptor');
  });

authService.js

// authService.js

angular.module('authService', [])
  // ============================================
  //auth factory to login and get information
  //inject $http for communicating with the API
  //inject $q to return promise objects
  //inject AuthToken to manage tokens
  // ============================================

  .factory('Auth', function($http, $q, AuthToken){
    //create auth factory object
    var authFactory = {};

    // handle login for users
    // Post request to /api/authenticate
    authFactory.login = function(username, password){
      //return the promise object and its data
      return $http.post('/api/authenticate', {
        username: username,
        password: password
      })
        .success(function(data){
          AuthToken.setToken(data.token);
          return data;
        });
    };

    //log a user out by clearing the token useing AuthToken factory
    authFactory.logout = function(){
      //clear the token
      AuthToken.setToken();
    };

    //check if a user is logged in and check if there is a local token
    authFactory.isLoggedIn = function(){
      if(AuthToken.getToken())
        return true;
      else
        return false;
    };

    //get the logged in user
    authFactory.getUser = function(){
      if(AuthToken.getToken())
        return $http.get('/api/me');
      else
        return $q.reject({message: "User doesn't have a token"});
    };

    //return auth factory object
    return authFactory;
  })//End Auth

  // ============================================
  // factory for handling tokens
  // inject $window to store token on the client-side
  // ============================================

  .factory('AuthToken', function($window){
    var authTokenFactory = {};

    //get the token out of local storage
    authTokenFactory.getToken = function(){
      return $window.localStorage.getItem('token');
    };

    //set the token or clear the token
    //if token is passed, set token - if there is no token, clear it from local storage
    authTokenFactory.setToken = function(token){
      if(token)
        $window.localStorage.setItem('token', token);
      else
        $window.localStorage.removeItem('token');
    };

    //return auth token factory
    return authTokenFactory;
  })//End AuthToken

  // ============================================
  // application configuration to integrate token into requests
  // ============================================

  .factory('AuthInterceptor', function($q, $location, AuthToken){
    var interceptorFactory = {};

    //attach the token to all HTTP requests
    interceptorFactory.request = function(config){
      //grab the token
      var token = AuthToken.getToken();

      //If token exists then add it to the header as x-access-token
      if(token)
        config.headers['x-access-token'] = token;
        console.log(config);
      return config;
    };

    //On response errors

    interceptorFactory.responseError = function(response){
      //If server returns a 403 forbidden response
      if(response.status == 403)
        $location.path('/login');

      //return the errors from the server as a promise
      return $q.reject(response);
    }

    //return interceptorFactory
    return interceptorFactory;
  });//End AuthInterceptor
2

2 Answers

1
votes

In the request interceptor you can use config.url to see if request is going to other api.

Following is an update to your existing code in the interceptor

//attach the token to all HTTP requests - except weather API
interceptorFactory.request = function (config) {
    var isWeatherAPI = config.url.indexOf('api.openweathermap.org') > -1;
    // don't modify weather api headers
    if (!isWeatherAPI) {
        //grab the token
        var token = AuthToken.getToken();
        //If token exists then add it to the header as x-access-token
        if (token) {
            config.headers['x-access-token'] = token;
        }
    }

    return config;
};
0
votes

When you are sending the token instead of "x-access-token" try headers.Authorization = "Bearer " + token;