2015-08-11 6 views
2


Есть ли способ сбросить данные на заводе/сервисе в угловом режиме без создания зависимости от него?Сброс Угловой сервис

В настоящее время у меня есть AuthService, который берет имя пользователя и пароль и получает маркер oauth с сервера. У меня также есть HTTP-перехватчик, который добавляет токен ко всем запросам.

Если я получаю ответ 401 (несанкционированный), то мой токен больше недействителен, и я хочу установить _AuthData внутри AuthService в значение null. Но сейчас у меня нет хорошего способа сделать это.

Если я добавлю зависимость AuthService в перехватчик (чтобы иметь возможность вызвать LogOut()), я получаю круговую ссылку, поскольку AuthService использует $ http.

Я продолжаю перечитывать токен из localstorageservice внутри AuthService для таких методов, как IsAuthenticated() и Username(), но я бы хотел избежать этого, если это возможно, чтобы избежать удара производительности.

Есть ли способ «перезагрузить» AuthService из AuthInterceptorService, не создавая зависимость?

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

Я могу придумать несколько вариантов, переменно разумным.

  1. Просто первое, что нужно учитывать - это поразительное впечатление от локального хранилища, действительно, проблема для вас? Ваше текущее решение прост и понятен, и это само по себе.

  2. Разделить AuthService на Authorizer и AuthStorage. Таким образом Authorizer может зависеть от $http, AuthStorage не нужно, и AuthInterceptorService тогда зависит от AuthStorage, где вы можете поместить функцию сброса.

  3. Это один чувствует, как большой молоток, но AuthInterceptorService может транслировать auth_failed событие на appRoot, который AuthService может прослушивать, чтобы выполнить сброс. Это направляется к довольно глобальному прохождению сообщений, поэтому я буду обеспокоен его ремонтопригодностью.

+1

Спасибо за ваши предложения Кристьян. Я решил пойти с вариантом 2, поскольку это похоже на самое чистое и удобное решение. Чтобы ответить на # 1, даже если удар производительности не огромен, кажется немного нелепым, чтобы он мог напрямую считывать/записывать перехватчики и из локального хранилища. независимо от AuthService. –

+0

Согласен на оба счета, удачи! –

Смежные вопросы