docs: function getAuthorizationAsync(params, callback) {
  
      var headers = util.clone(params.Headers);
      delete headers['Content-Type'];
      delete headers['Cache-Control'];
      util.each(headers, function (v, k) {
          v === '' && delete headers[k];
      });
  
      var cb = function (AuthData) {
  
          // 检查签名格式
          var formatAllow = false;
          var auth = AuthData.Authorization;
          if (auth) {
              if (auth.indexOf(' ') > -1) {
                  formatAllow = false;
              } else if (auth.indexOf('q-sign-algorithm=') > -1 &&
                  auth.indexOf('q-ak=') > -1 &&
                  auth.indexOf('q-sign-time=') > -1 &&
                  auth.indexOf('q-key-time=') > -1 &&
                  auth.indexOf('q-url-param-list=') > -1) {
                  formatAllow = true;
              } else {
                  try {
                      auth = atob(auth);
                      if (auth.indexOf('a=') > -1 &&
                          auth.indexOf('k=') > -1 &&
                          auth.indexOf('t=') > -1 &&
                          auth.indexOf('r=') > -1 &&
                          auth.indexOf('b=') > -1) {
                          formatAllow = true;
                      }
                  } catch (e) {}
              }
          }
          if (formatAllow) {
              callback && callback(null, AuthData);
          } else {
              callback && callback('authorization error');
          }
      };
  
      var self = this;
      var Bucket = params.Bucket || '';
      var Region = params.Region || '';
  
      // PathName
      var KeyName = params.Key || '';
      if (self.options.ForcePathStyle && Bucket) {
          KeyName = Bucket + '/' + KeyName;
      }
      var Pathname = '/' + KeyName;
  
      // Action、ResourceKey
      var StsData = {};
      var Scope = params.Scope;
      if (!Scope) {
          var Action = params.Action || '';
          var ResourceKey = params.ResourceKey || params.Key || '';
          Scope = params.Scope || [{
              action: Action,
              bucket: Bucket,
              region: Region,
              prefix: ResourceKey,
          }];
      }
      var ScopeKey  = util.md5(JSON.stringify(Scope));
  
      // STS
      self._StsCache = self._StsCache ||[];
      (function () {
          var i, AuthData;
          for (i = self._StsCache.length - 1; i >= 0; i--) {
              AuthData = self._StsCache[i];
              var compareTime = Math.round(util.getSkewTime(self.options.SystemClockOffset) / 1000) + 30;
              if (AuthData.StartTime && compareTime < AuthData.StartTime || compareTime >= AuthData.ExpiredTime) {
                  self._StsCache.splice(i, 1);
                  continue;
              }
              if (!AuthData.ScopeLimit || AuthData.ScopeLimit && AuthData.ScopeKey === ScopeKey) {
                  StsData = AuthData;
                  break;
              }
          }
      })();
  
      var calcAuthByTmpKey = function () {
          var Authorization = util.getAuth({
              SecretId: StsData.TmpSecretId,
              SecretKey: StsData.TmpSecretKey,
              Method: params.Method,
              Pathname: Pathname,
              Query: params.Query,
              Headers: headers,
              UseRawKey: self.options.UseRawKey,
              SystemClockOffset: self.options.SystemClockOffset,
          });
          var AuthData = {
              Authorization: Authorization,
              XCosSecurityToken: StsData.XCosSecurityToken || '',
              Token: StsData.Token || '',
              ClientIP: StsData.ClientIP || '',
              ClientUA: StsData.ClientUA || '',
          };
          cb(AuthData);
      };
  
      // 先判断是否有临时密钥
      if (StsData.ExpiredTime && StsData.ExpiredTime - (util.getSkewTime(self.options.SystemClockOffset) / 1000) > 60) { // 如果缓存的临时密钥有效，并还有超过60秒有效期就直接使用
          calcAuthByTmpKey();
      } else if (self.options.getAuthorization) { // 外部计算签名或获取临时密钥
          self.options.getAuthorization.call(self, {
              Bucket: Bucket,
              Region: Region,
              Method: params.Method,
              Key: KeyName,
              Pathname: Pathname,
              Query: params.Query,
              Headers: headers,
              Scope: Scope,
          }, function (AuthData) {
              if (typeof AuthData === 'string') {
                  AuthData = {Authorization: AuthData};
              }
              if (AuthData.TmpSecretId &&
                  AuthData.TmpSecretKey &&
                  AuthData.XCosSecurityToken &&
                  AuthData.ExpiredTime) {
                  StsData = AuthData || {};
                  StsData.Scope = Scope;
                  StsData.ScopeKey = ScopeKey;
                  self._StsCache.push(StsData);
                  calcAuthByTmpKey();
              } else {
                  cb(AuthData);
              }
          });
      } else if (self.options.getSTS) { // 外部获取临时密钥
          self.options.getSTS.call(self, {
              Bucket: Bucket,
              Region: Region,
          }, function (data) {
              StsData = data || {};
              StsData.Scope = Scope;
              StsData.ScopeKey = ScopeKey;
              StsData.TmpSecretId = StsData.SecretId;
              StsData.TmpSecretKey = StsData.SecretKey;
              self._StsCache.push(StsData);
              calcAuthByTmpKey();
          });
      } else { // 内部计算获取签名
          return (function () {
              var Authorization = util.getAuth({
                  SecretId: params.SecretId || self.options.SecretId,
                  SecretKey: params.SecretKey || self.options.SecretKey,
                  Method: params.Method,
                  Pathname: Pathname,
                  Query: params.Query,
                  Headers: headers,
                  Expires: params.Expires,
                  UseRawKey: self.options.UseRawKey,
                  SystemClockOffset: self.options.SystemClockOffset,
              });
              var AuthData = {
                  Authorization: Authorization,
                  XCosSecurityToken: self.options.XCosSecurityToken,
              };
              cb(AuthData);
              return AuthData;
          })();
      }
      return '';
  }