重置 Angular 服务
Reset Angular Service
有没有一种好的方法可以在 angular 中重置 factory/service 中的数据而不创建对它的依赖?
我目前有一个 AuthService,它接受用户名和密码,并从服务器获取 oauth 令牌。我还有一个将令牌添加到所有请求的 http 拦截器。
如果我收到 401(未经授权)响应,则我的令牌不再有效,我想将 AuthService 中的 _AuthData 设置为 null。但是我现在没有很好的方法来做到这一点。
如果我将 AuthService 依赖项添加到拦截器中(以便能够调用 LogOut()),那么我会得到一个循环引用,因为 AuthService 使用 $http。
我一直在为 IsAuthenticated() 和 Username() 等方法从 AuthService 中的本地存储服务重新读取令牌,但我想尽可能避免这种情况,以避免性能受到影响。
有没有办法从 AuthInterceptorService "reset" AuthService 而不创建依赖关系?
AuthService
appRoot.factory("AuthService", ["$http", "$q", "localStorageService", function ($http, $q, localStorageService) {
var _AuthData;
var AuthServiceFactory = {};
AuthServiceFactory.Username = function () {
return _AuthData.Username;
};
AuthServiceFactory.Roles = function () {
return _AuthData.Roles;
};
AuthServiceFactory.IsAuthenticated = function () {
return _AuthData != null;
};
AuthServiceFactory.LogOut = function () {
_AuthData = null;
localStorageService.remove("AuthData");
};
AuthServiceFactory.Login = function (Username, Password) {
var Deferred = $q.defer();
$http.post(ApiBaseUrl + "token", Username, { headers: { 'Content-Type': "application/x-www-form-urlencoded" } }).success(function (Response) {
_AuthData = {
Token: Response.access_token,
Username: Username,
Roles: Response.Roles
};
localStorageService.set("AuthData", _AuthData);
Deferred.resolve(Response);
}).error(function (err, status) {
Deferred.reject(err);
});
return Deferred.promise;
};
return AuthServiceFactory;
}]);
AuthInterceptorService
appRoot.factory("AuthInterceptorService", ["$q", "$location", "localStorageService", function ($q, $location, localStorageService) {
var AuthInterceptorServiceFactory = {};
AuthInterceptorServiceFactory.request = function (config) {
config.headers = config.headers || {};
var AuthData = localStorageService.get("AuthData");
if (AuthData) {
config.headers.Authorization = "Bearer " + AuthData.Token;
}
return config;
};
AuthInterceptorServiceFactory.responseError = function (Rejection) {
if (Rejection.status === 401) {
localStorageService.remove("AuthData");
//AuthService.LogOut(); //Need to reset token here
$location.url("/Login");
}
return $q.reject(Rejection);
};
return AuthInterceptorServiceFactory;
}]);
我能想到几个选项,各不相同。
首先要考虑的是 - 本地存储对性能的影响对您来说真的是个问题吗?您当前的解决方案简单易懂,这本身就是一个特点。
将 AuthService
拆分为 Authorizer
和 AuthStorage
。这样 Authorizer
可以依赖于 $http
,AuthStorage
不需要,然后 AuthInterceptorService
可以依赖于 AuthStorage
,你可以在其中放置重置函数.
这个感觉像个大锤子,但是AuthInterceptorService
可以在appRoot
上广播一个auth_failed
事件,AuthService
可以监听执行重置。这正朝着相当全球化的消息传递方向发展,所以我会担心它的可维护性。
有没有一种好的方法可以在 angular 中重置 factory/service 中的数据而不创建对它的依赖?
我目前有一个 AuthService,它接受用户名和密码,并从服务器获取 oauth 令牌。我还有一个将令牌添加到所有请求的 http 拦截器。
如果我收到 401(未经授权)响应,则我的令牌不再有效,我想将 AuthService 中的 _AuthData 设置为 null。但是我现在没有很好的方法来做到这一点。
如果我将 AuthService 依赖项添加到拦截器中(以便能够调用 LogOut()),那么我会得到一个循环引用,因为 AuthService 使用 $http。
我一直在为 IsAuthenticated() 和 Username() 等方法从 AuthService 中的本地存储服务重新读取令牌,但我想尽可能避免这种情况,以避免性能受到影响。
有没有办法从 AuthInterceptorService "reset" AuthService 而不创建依赖关系?
AuthService
appRoot.factory("AuthService", ["$http", "$q", "localStorageService", function ($http, $q, localStorageService) {
var _AuthData;
var AuthServiceFactory = {};
AuthServiceFactory.Username = function () {
return _AuthData.Username;
};
AuthServiceFactory.Roles = function () {
return _AuthData.Roles;
};
AuthServiceFactory.IsAuthenticated = function () {
return _AuthData != null;
};
AuthServiceFactory.LogOut = function () {
_AuthData = null;
localStorageService.remove("AuthData");
};
AuthServiceFactory.Login = function (Username, Password) {
var Deferred = $q.defer();
$http.post(ApiBaseUrl + "token", Username, { headers: { 'Content-Type': "application/x-www-form-urlencoded" } }).success(function (Response) {
_AuthData = {
Token: Response.access_token,
Username: Username,
Roles: Response.Roles
};
localStorageService.set("AuthData", _AuthData);
Deferred.resolve(Response);
}).error(function (err, status) {
Deferred.reject(err);
});
return Deferred.promise;
};
return AuthServiceFactory;
}]);
AuthInterceptorService
appRoot.factory("AuthInterceptorService", ["$q", "$location", "localStorageService", function ($q, $location, localStorageService) {
var AuthInterceptorServiceFactory = {};
AuthInterceptorServiceFactory.request = function (config) {
config.headers = config.headers || {};
var AuthData = localStorageService.get("AuthData");
if (AuthData) {
config.headers.Authorization = "Bearer " + AuthData.Token;
}
return config;
};
AuthInterceptorServiceFactory.responseError = function (Rejection) {
if (Rejection.status === 401) {
localStorageService.remove("AuthData");
//AuthService.LogOut(); //Need to reset token here
$location.url("/Login");
}
return $q.reject(Rejection);
};
return AuthInterceptorServiceFactory;
}]);
我能想到几个选项,各不相同。
首先要考虑的是 - 本地存储对性能的影响对您来说真的是个问题吗?您当前的解决方案简单易懂,这本身就是一个特点。
将
AuthService
拆分为Authorizer
和AuthStorage
。这样Authorizer
可以依赖于$http
,AuthStorage
不需要,然后AuthInterceptorService
可以依赖于AuthStorage
,你可以在其中放置重置函数.这个感觉像个大锤子,但是
AuthInterceptorService
可以在appRoot
上广播一个auth_failed
事件,AuthService
可以监听执行重置。这正朝着相当全球化的消息传递方向发展,所以我会担心它的可维护性。