重置角度服务

时间:2015-08-11 14:54:35

标签: angularjs angularjs-service


有没有一种很好的方法可以在角度重置工厂/服务中的数据而不会产生依赖性?

我目前有一个AuthService,它接受用户名和密码,并从服务器获取一个oauth令牌。我还有一个http拦截器,它将令牌添加到所有请求中。

如果我收到401(未经授权的)响应,那么我的令牌不再有效,我想将AuthService中的_AuthData设置为null。但我现在没有办法做到这一点。

如果我在拦截器中添加一个AuthService依赖(为了能够调用LogOut()),那么我得到一个循环引用,因为AuthService使用$ http。

我继续从AuthService内的localstorageservice中读取令牌,例如IsAuthenticated()和Username(),但我想避免这种情况,以避免性能损失。

有没有办法在不创建依赖性的情况下从AuthInterceptorService“重置”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;
}]);

1 个答案:

答案 0 :(得分:1)

我可以想到一些不同的选择。

  1. 首先要考虑的是 - 本地存储的性能是否对您来说真的是一个问题?您当前的解决方案简单明了,易于理解,而且这本身就是一个功能。

  2. AuthService分成AuthorizerAuthStorage。这样Authorizer可能取决于$httpAuthStorage不需要,AuthInterceptorService可以依赖AuthStorage,您可以在AuthInterceptorService放置重置功能。<​​/ p>

  3. 这个感觉就像一个大锤子,但auth_failed可以在appRoot上播放AuthService事件,item().children.length > foo().maxChildren可以监听以执行重置。这种情况正朝着漂亮的全球信息传递方向发展,因此我担心其可维护性。