2015-10-23 50 views
0

我一直试图通过angular-upload将Cloudinary集成到我的AngularJS应用程序中。但是,我也遇到过当试图从我的应用程序上传此错误:Angular-JWT授权标头例外

Authorization is not allowed by Access-Control-Allow-Headers

起初我以为这是一个繁重的问题,因为我是使用HTTP的服务器来运行Cloudinary示例应用程序,其成功上传,但我现在意识到这更可能是使用Auth0的angular-jwt实现的结果。这是将授权标头附加到所有请求,这是cloudinary不接受的。我发现有人用非常类似的问题在这里不过,我有麻烦搞清楚如何去适应这样的解决方案,以角智威汤逊

https://github.com/DaftMonk/generator-angular-fullstack/issues/931

。我叫

$httpProvider.interceptors.push('jwtInterceptor');

在我的app.config,但我想它排除请求https://api.cloudinary.com/v1_1/

这是角智威汤逊分布:

(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() > (new Date().valueOf() + (offsetSeconds * 1000))); 
    }; 
    }); 

}()); 

帮助?

回答

3

jwtInterceptor检查一个skipAuthorization标志该请求,并且,如果它被设置为true不发送授权报头。

建立你的$ HTTP调用像

$http({ 
    url: 'https://api.cloudinary.com/v1_1/', 
    skipAuthorization: true, 
    method: 'POST', 
    // ... etc 
}).then(successCallback, errorCallback); 

- 更多的angular-jwt Docs

+0

哇,这么容易,我花了这么多时间试图弄明白。谢谢! – cassiusclay

+0

我也很难找出类似的问题。我正在开发客户端和服务器端代码,并且服务器端代码期望OPTIONS请求的有效授权标头(在任何其他请求之前由框架执行)。我删除了OPTIONS的授权验证,并完成了这项工作。 – Cotta