【问题标题】:Angular-JWT Authorization header exceptionAngular-JWT 授权标头异常
【发布时间】:2016-01-22 11:08:31
【问题描述】:

我一直在尝试通过 angular-upload 将 Cloudinary 集成到我的 AngularJS 应用程序中。但是,我在尝试从我的应用上传时遇到了这个错误:

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

起初我认为这是一个棘手的问题,因为我使用 http-server 运行 Cloudinary 示例应用程序,该应用程序已成功上传,但我现在意识到这更有可能是使用 Auth0 的 angular-jwt 实现的结果。这是将 Authorization 标头附加到 cloudinary 不接受的所有请求。我在这里找到了一个非常相似的问题

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

但是,我无法弄清楚如何使这种解决方案适应 angular-jwt。我打电话给

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

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

这是 angular-jwt 分布:

(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)));
    };
  });

}());

帮助?

【问题讨论】:

    标签: javascript angularjs cors jwt auth0


    【解决方案1】:

    jwtInterceptor 检查skipAuthorization 标志的请求,如果设置为true,则不发送授权标头。

    像这样构建你的 $http 调用

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

    - 更多信息请访问angular-jwt Docs

    【讨论】:

    • 哇,太容易了,我花了很多时间试图弄清楚。谢谢!
    • 我也很难找到类似的问题。我正在开发客户端和服务器端代码,服务器端代码期望 OPTIONS 请求的有效授权标头(在任何其他请求之前由框架执行)。我删除了 OPTIONS 的授权验证,它完成了这项工作。
    猜你喜欢
    • 2020-07-26
    • 1970-01-01
    • 2015-11-05
    • 2019-09-23
    • 2016-07-15
    • 2018-09-16
    • 2017-07-01
    • 1970-01-01
    相关资源
    最近更新 更多