title: Angular-JWT Authorization header exception
body: <p>I've been trying to integreate Cloudinary via angular-upload into my AngularJS app.  However, I have encountered this error when attempting to upload from my app:</p>
  
  <p><code>Authorization is not allowed by Access-Control-Allow-Headers</code></p>
  
  <p>At first I thought this was a grunt issue since I was using http-server to run the Cloudinary sample app, which uploaded successfully, but I have now realized this is more likely a result of using Auth0's angular-jwt implementation.  This is attaching the Authorization header to all requests, which cloudinary does not accept.  I found someone with a very similar problem here</p>
  
  <p><a href="https://github.com/DaftMonk/generator-angular-fullstack/issues/931" rel="nofollow">https://github.com/DaftMonk/generator-angular-fullstack/issues/931</a></p>
  
  <p>however, I'm having trouble figuring out how to adapt such a solution to angular-jwt.  I call </p>
  
  <p><code>$httpProvider.interceptors.push('jwtInterceptor');</code> </p>
  
  <p>in my app.config, but I want it to exclude requests to <code>https://api.cloudinary.com/v1_1/</code> </p>
  
  <p>This is the angular-jwt distribution:</p>
  
  <pre><code>(function() {
  
  
  // Create all modules and define dependencies to make sure they exist
  // and are loaded in the correct order to satisfy dependency injection
  // before all nested files are concatenated by Grunt
  
  // Modules
  angular.module('angular-jwt',
      [
          'angular-jwt.interceptor',
          'angular-jwt.jwt'
      ]);
  
   angular.module('angular-jwt.interceptor', [])
    .provider('jwtInterceptor', function() {
  
      this.urlParam = null;
      this.authHeader = 'Authorization';
      this.authPrefix = 'Bearer ';
      this.tokenGetter = function() {
        return null;
      }
  
      var config = this;
  
      this.$get = ["$q", "$injector", "$rootScope", function ($q, $injector, $rootScope) {
        return {
          request: function (request) {
            if (request.skipAuthorization) {
              return request;
            }
  
            if (config.urlParam) {
              request.params = request.params || {};
              // Already has the token in the url itself
              if (request.params[config.urlParam]) {
                return request;
              }
            } else {
              request.headers = request.headers || {};
              // Already has an Authorization header
              if (request.headers[config.authHeader]) {
                return request;
              }
            }
  
            var tokenPromise = $q.when($injector.invoke(config.tokenGetter, this, {
              config: request
            }));
  
            return tokenPromise.then(function(token) {
              if (token) {
                if (config.urlParam) {
                  request.params[config.urlParam] = token;
                } else {
                  request.headers[config.authHeader] = config.authPrefix + token;
                }
              }
              return request;
            });
          },
          responseError: function (response) {
            // handle the case where the user is not authenticated
            if (response.status === 401) {
              $rootScope.$broadcast('unauthenticated', response);
            }
            return $q.reject(response);
          }
        };
      }];
    });
  
   angular.module('angular-jwt.jwt', [])
    .service('jwtHelper', function() {
  
      this.urlBase64Decode = function(str) {
        var output = str.replace(/-/g, '+').replace(/_/g, '/');
        switch (output.length % 4) {
          case 0: { break; }
          case 2: { output += '=='; break; }
          case 3: { output += '='; break; }
          default: {
            throw 'Illegal base64url string!';
          }
        }
        return decodeURIComponent(escape(window.atob(output))); //polifyll https://github.com/davidchambers/Base64.js
      }
  
  
      this.decodeToken = function(token) {
        var parts = token.split('.');
  
        if (parts.length !== 3) {
          throw new Error('JWT must have 3 parts');
        }
  
        var decoded = this.urlBase64Decode(parts[1]);
        if (!decoded) {
          throw new Error('Cannot decode the token');
        }
  
        return JSON.parse(decoded);
      }
  
      this.getTokenExpirationDate = function(token) {
        var decoded;
        decoded = this.decodeToken(token);
  
        if(typeof decoded.exp === "undefined") {
          return null;
        }
  
        var d = new Date(0); // The 0 here is the key, which sets the date to the epoch
        d.setUTCSeconds(decoded.exp);
  
        return d;
      };
  
      this.isTokenExpired = function(token, offsetSeconds) {
        var d = this.getTokenExpirationDate(token);
        offsetSeconds = offsetSeconds || 0;
        if (d === null) {
          return false;
        }
  
        // Token expired?
        return !(d.valueOf() &gt; (new Date().valueOf() + (offsetSeconds * 1000)));
      };
    });
  
  }());
  </code></pre>
  
  <p>Help?</p>