0

状況: 1 つのページの読み込みとメイン モジュールから実行されるデバイス アプリケーションを開発しています。アプリケーションは、2 つの API 呼び出しを介して通信します。アプリケーションは、POST 経由で送信された「/api/login」への API 呼び出しから取得された現在の認証状態を必要とします。ビュー レンダリングのデータを保存および設定するために使用される API 呼び出しは、POST 経由で「/api」に送信される API 呼び出しによって伝達されます。どちらの呼び出しも、同じ protocol://domain:port に対して行われます。

問題: IE9 のみで、Chrome と FF が期待どおりに動作し、返されたデータが "/api" への 2 番目の API 呼び出しに対して有効ではありません。IE9 では、開発者ツールのネットワーク パネルに、実行されると想定されるすべてのパラメーターを使用して "/api" への呼び出しが行われていることが示されます。ただし、応答には、無効なパラメーターを使用してログイン API を呼び出しているかのような失敗応答が表示されます。

$http.post が両方の呼び出しですぐに期限切れになるように構成していて、両方の呼び出しでキャッシュが false に設定されているにもかかわらず、これはどのように可能ですか? どうすれば修正または回避できますか? 以下は私が使用しているコードです。

編集: Windows 7 ThinkPad からこれを表示していることを忘れていました。

index.js からのコード:

var LocalPortal = angular.module('LocalPortal', ['ngResource'])
.value('lpApi', {
_apiList : [],
_apiUri : '/api',
_functionStack : {},
_host : document.location.hostname,
_port : 8080,
_protocol : document.location.protocol,
_sessionTimeout : 900,
_addToCallStack : function(param) {
  this._functionStack = $.extend(this._functionStack, param);
},
_doApiCall : function(dataSegment, command, params) {
  var segment = {};
  segment[dataSegment] = {"command" : command};
  if (params) {
    segment[dataSegment]["params"] = params;
  }
  this._addToCallStack(segment);
  $.subscribe('api.received', function(e,data) {
    $.publish(command, data[dataSegment]);
  });
},
_restoreAuthState : function() {
  var _authState = (sessionStorage.getItem('lpApi.authState')) ? JSON.parse(sessionStorage.getItem('lpApi.authState')) : {};
  lpApi.authState = _authState;
},
_setAuthTime : function(timeVal) {
  lpApi.authState.authTime = timeVal;
  lpApi._storeAuthState();
},
_storeAuthState : function() {
  sessionStorage.setItem('lpApi.authState', JSON.stringify(lpApi.authState));
},
_url : function() {
  return this._protocol + '//'
          + this._host +
          (this._port ? ':' + this._port : '')
  + this._apiUri;
},
apiList : function() {
  this._doApiCall("apiList", "api.list");
  return this;
},
getPayload : function() {
  var payload = this._functionStack;
  this._functionStack = {};
  return payload;
},
getUrl : function(uriExt) {
  return this._url() + uriExt;
},
init : function(){
  var loc = document.location;

  this._apiList = sessionStorage.getItem('apiList');
  this._host = loc.hostname;
  this._port = loc.port;
  this._protocol = loc.protocol;

  //store a reference to this object for later callbacks to access
  window.lpApi = this;

  //restore authentication state if any
  lpApi._restoreAuthState();
},
logOff : function() {
  lpApi._setAuthTime(0);
  sessionStorage.removeItem('lpApi.authState');
}
})
.config(function($routeProvider) {
$routeProvider.
  when('/login', {templateUrl: 'partials/login.html', controller: LoginCtrl}).
  when('/home', {templateUrl: 'partials/gateway.html', controller: GatewayCtrl}).
  when('/gateway', {templateUrl: 'partials/gateway.html', controller: GatewayCtrl}).
  when('/assets', {templateUrl: 'partials/assets.html', controller: AssetsCtrl}).
  when('/connectivity', {templateUrl: 'partials/connectivity.html', controller: ConnectivityCtrl}).
  when('/events', {templateUrl: 'partials/events.html', controller: EventsCtrl}).
  otherwise({redirectTo:'/home', templateUrl: 'partials/gateway.html', controller: GatewayCtrl});
for (var that in this) {
  if (that.substr(-4) == 'Ctrl') {
    if (this[that].prototype.menu) {
      for (var index in this[that].prototype.menu.items) {
        $routeProvider.
          when(this[that].prototype.menu.items[index].href, {
            templateUrl: this[that].prototype.menu.items[index].template,
            controller: that
          });
      }
    }
    if (this[that].prototype.ctrlActions) {
      for (var index in this[that].prototype.ctrlActions.items) {
        $routeProvider.
          when(this[that].prototype.ctrlActions.items[index].href, {
            templateUrl: this[that].prototype.ctrlActions.items[index].template,
            controller: that
          });
      }
    }
    if (this[that].prototype.mainActions) {
      for (var index in this[that].prototype.mainActions.items) {
        $routeProvider.
          when(this[that].prototype.mainActions.items[index].href, {
            templateUrl: this[that].prototype.mainActions.items[index].template,
            controller: that
          });
      }
    }

    if (this[that].prototype.secondaryActions) {
      for (var index in this[that].prototype.secondaryActions.items) {
        $routeProvider.
          when(this[that].prototype.secondaryActions.items[index].href, {
            templateUrl: this[that].prototype.secondaryActions.items[index].template,
            controller: that
          });
      }
    }
  }
}
})
.directive('appTopMenu', function() {
return {
  restrict: 'E',
  templateUrl: 'partials/top-menu.html'
}
})
.directive('appMenu', function() {
return {
  restrict: 'E',
  templateUrl: 'partials/menu.html',
  link: function(scope,element,attr) {
    for (var that in this) {
      if (that.substr(-4) == 'Ctrl') {
        if (this[that].prototype.menu) {
          for (var index in this[that].prototype.menu.items) {
            scope.menu.items[scope.menu.items.length] = this[that].prototype.menu.items[index];
          }
        }
      }
    }
  }
}
})
.run(function(){
});

var IndexCtrl = function($scope, lpApi, $location) {
//Properties
$scope._localPortalContainer = 'container';

$scope._loggedIn = true;

//Functions
$scope.assertAuthentication = function() {
if(!$scope.isAuthenticated()){
  lpApi.logOff();
  $scope.setRouteReload('/login');
}
};

$scope.getLocalPortalContainer = function() {
return $scope._localPortalContainer;
};

$scope.getLoggedInStatus = function() {
return $scope._loggedIn;
};

$scope.isAuthenticated = function() {
if (sessionStorage) {
  if (sessionStorage.getItem('lpApi.authState')) {
    lpApi.init();
    return ((new Date().getTime() - lpApi.authState.authTime) < 900000);
  }
  else {
    lpApi.init();
    return false;
  }
}
return false;
};

$scope.setErrorMsg = function(msg) {
$scope.errorMsg = msg;
};

$scope.setLocalPortalContainer = function($container){
$scope._localPortalContainer = $container;
};

$scope.setLoggedInStatus = function(status) {
$scope._loggedIn = status;
};

$scope.setRoute = function($route) {
$location.path($route);
};

$scope.setRouteReload = function($route) {
$location.path($route);
document.location.reload();
};

if (!$scope.isAuthenticated()) {
$scope.setLocalPortalContainer('container-small');
$scope.setLoggedInStatus(false);
$scope.setRoute('/login');
}
};

IndexCtrl.$inject = ['$scope', 'lpApi', '$location'];

login.js のコード:

var LoginCtrl = function($scope, $http, lpApi) {

// Functions
$scope.authenticate = function(username, password, $http){
var data = {auth: {username: username, password: password}};

$http.post(lpApi.getUrl('')+'/login', data, {cache: false, headers: {Expires: -1}})
  .error($scope.postError)
  .success($scope.setAuthState);
};

$scope.login = function($scope, lpApi) {
if($scope.isAuthenticated() && lpApi.logOff) {
  lpApi.logOff();
  $scope.setRouteReload('/login');
}
$scope.setLocalPortalContainer('container-small');
$scope.setLoggedInStatus(false);
};

$scope.postError = function(data, status, headers, config){
// output error message
$scope.setErrorMsg(data.errorMessage[0])
};

$scope.setAuthState = function(data, status, headers, config){
lpApi.authState.sessionId = data.sessionId || null;
lpApi.authState.roles = data.roles || null;
lpApi.authState.requirePasswordChange = data.requirePasswordChange || null;
lpApi.authState.success = data.success;
if (data.success) {
  lpApi._setAuthTime(new Date().getTime());
  $scope.setLocalPortalContainer('container');
  $scope.setLoggedInStatus(true);
  $scope.setRoute('/home');
}
else {
  // output error message
  $scope.setErrorMsg(data.errorMessage[0])
}
};

$scope.submit = function(){
$scope.authenticate(this.input_username, this.input_password, $http);
};

$scope.login($scope, lpApi);
};

LoginCtrl.$inject = ['$scope', '$http', 'lpApi'];

gateway.js のコード:

var GatewayCtrl = function($scope, lpApi, $http) {
lpApi.cloudlinkInfo();

lpApi.loggingQuery({limit:"5",page:"0"});

lpApi.modemInfo();

lpApi.osInfo();

lpApi.systemNodeinfo();

lpApi.systemProductinfo();

lpApi.tunnelInfo();

// Properties
$scope.loadData = function(data, status, headers, config) {
console.log('succes'); 
console.log(JSON.stringify(data)); // {"success":false,"errorMessage":["Invalid authentication."]} (See config url is not "/api/login")
console.log(status);
console.log(headers);
console.log(JSON.stringify(config)); // {"method":"POST","url":"protocol://domain:port/api","data":{"cloudlinkInfo": {"command":"cloudlink.info"},"loggingQuery" "command":"logging.query","params":{"limit":"5","page":"0"}},"modemInfo": "command":"modem.info"},"osInfo":{"command":"os.info"},"systemNodeinfo": "command":"system.nodeinfo"},"systemProductinfo" : {"command":"system.productinfo"},"tunnelInfo":{"command":"tunnel.info"}}}
};

$scope.postError = function(data, status, headers, config) {
console.log('error');
console.log(JSON.stringify(data));
console.log(status);
console.log(headers);
console.log(JSON.stringify(config));
};

$scope.assertAuthentication(); // <== asserts we have a current authState.

var payload = lpApi.getPayload(), apiUrl = lpApi.getUrl(''); // <== payload is an object of api calls and their params, apiUrl is protocol://domain:port/api

$http.post(apiUrl, payload).error($scope.postError).success($scope.loadData);
};

GatewayCtrl.$inject = ['$scope', 'lpApi', '$http'];
4

1 に答える 1

0

「無効な認証」応答は、実際には有効な応答でした。デバイスの Web サービスが設定していた Cookie が IE9 の期待どおりに不完全であり、IE9 がそれをすべて無視していたことが判明しました。Chrome と FF ははるかに寛容です。

于 2012-06-28T17:38:46.993 に答える