AngularJS Маршруты и разрешение с новой аутентификацией Firebase

Я пытаюсь использовать новую Firebase с системой аутентификации и ограничиваю маршруты в моем $routeProvider с помощью resolves,

Однако я не совсем понимаю.

Это то, что у меня есть. В моей функции.config я определяю маршруты и инициализирую firebase. Следующее находится в моем блоке конфигурации.

$routeProvider
   .when('/', {
      templateUrl: 'templates/dashboard.ejs',
      //resolve. this needs restricted
   })
   .when('/login', {
      templateUrl: 'templates/login.ejs'
   })

firebase.initializeApp(config);

На новом сайте документации я обнаружил, что доступны эти функции, которые перечислены в моем .run() блок для угловых.

.run(function($rootScope, $location) {

    $rootScope.authentication = firebase.auth();

    /*firebase.auth().onAuthStateChanged(function(user) {
        if(user) {
            $rootScope.user = user;
        } else {
            $rootScope.user = false;
            $location.path('/login')
        }
    })*/

    var user = firebase.auth().currentUser;

    if (user) {
        $rootScope.user = user;
    } else {
        $rootScope.user = false;
        console.log('No User!');
        $location.path('/login');
    }
})

Теперь то, что я имею выше, это только стрельба every other time У меня есть доступ к любому URL на моем сайте.

Поэтому мой вопрос заключается в том, как мне взять то, что находится в моей функции.run(), и сделать это разрешением для моего routeProvider, чтобы я снова мог ограничивать маршруты.

В старом firebase вы просто вызывали бы $firebaseAuth(), как показано ниже, и имели бы функцию routeChangeError, которая была вызвана следующим образом.

// In config block. **old way**
$routeProvider
        .when('/', {
            templateUrl: 'templates/dashboard.ejs',
            resolve: {
                "currentAuth": ["$firebaseAuth", function($firebaseAuth) {
                    var ref = new Firebase(fbUrl);
                    var authObj = $firebaseAuth(ref);

                    return authObj.$requireAuth();
                }]
            }
        })

А затем ошибка routechangeer в блоке.run().

 // .run block **old way**
 .run(function($rootScope, $location) {
    $rootScope.$on("$routeChangeError", function(event, current, previous, eventObj) {
        if (eventObj === 'AUTH_REQUIRED') {
            console.log('auth required!');
            $location.path("/login");
        }
    });
})

Это больше не работает, потому что вы не используете $firebaseAuth() больше. или же new Firebase(fbUrl); в этом отношении либо.

ОБНОВИТЬ

Я чувствую, что это немного грязно, но, изучая маршруты немного больше, я придумал это.

В моем маршруте разрешите:

.when('/', {
            templateUrl: 'templates/dashboard.ejs',
            resolve: {
                userAuthenticated: ["$http", "$q", function($http, $q) {
                    var deferred = $q;
                    if(firebase.auth().currentUser) {
                        deferred.resolve();
                    } else {
                        deferred.reject();
                        console.log('Really!?');
                    }
                    return deferred.promise;
                }]
            }
        })  

А потом простой routeChangeError.

$rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {
        alert("Not authorised");
})

Единственная проблема заключается в том, что deferred.promise возвращается неопределенным. Это не активация функции routeChangeError. Хотя мой console.log() вызывается.

Может ли это быть потому, что firebase.auth().currentUser возвращает ноль, когда ни один пользователь не аутентифицирован?

2 ответа

Решение

Методы были переименованы в $waitForSignIn() а также $requireSignIn,

Вы также можете использовать $firebaseRefProvider сервис для настройки URL базы данных, чтобы он автоматически настраивал $firebaseAuthService,

angular.module('app', ['firebase'])
  .constant('FirebaseDatabaseUrl', '<my-firebase-url>')
  .controller('HomeCtrl', HomeController)
  .config(function($firebaseRefProvider, FirebaseDatabaseUrl, $routeProvider) {
     $firebaseRefProvider.registerUrl(FirebaseDatabaseUrl);
     $routeProvider.when("/home", {
        controller: "HomeCtrl",
        templateUrl: "views/home.html",
        resolve: {
          // controller will not be loaded until $waitForSignIn resolves
          "firebaseUser": function($firebaseAuthService) {
            return $firebaseAuthService.$waitForSignIn();
          }
        }
      }).when("/account", {
        controller: "AccountCtrl",
        templateUrl: "views/account.html",
        resolve: {
          // controller will not be loaded until $requireSignIn resolves
          "firebaseUser": function(Auth) {
            // If the promise is rejected, it will throw a $stateChangeError
            return $firebaseAuthService.$requireSignIn();
          }
        }
      });
  });

function HomeController($scope, $firebaseRef, firebaseUser) {

} 

Так что я не уверен, что это самый чистый кодовый код в мире, но он работает.

Firebase теперь предоставляет новую функцию для аутентификации текущего пользователя, если он есть. После инициализации firebase у вас есть доступ к этой функции. firebase.auth().currentUser,

(Эта функция возвращает данные пользователя, если залогинен, и ноль, если нет)

Таким образом, на вашем маршруте вы должны создать и разрешить обещание на основе результатов этой функции. Обязательно определите отложенное как $q.defer(); (Я боролся с этим, как вы можете видеть в моем обновлении вопроса)

    $routeProvider
    .when('/', {
            templateUrl: 'templates/dashboard.ejs',
            resolve: {
                userAuthenticated: ["$http", "$q", function($http, $q) {
                    var deferred = $q.defer();
                    if(firebase.auth().currentUser) {
                        deferred.resolve();
                    } else {
                        deferred.reject('NOT_AUTHORIZED');
                    }
                    return deferred.promise;
                }]
            }
        })  

А затем в функции запуска Angular вы будете следить за ошибками изменения маршрута.

.run(function($rootScope, $location) {
   $rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {
      if(rejection == 'NOT_AUTHORIZED')
      {
         $location.path('/login');
      }
    })
})

В приведенной выше функции вы просто наблюдаете за ошибкой в ​​изменении маршрута. Если отклонение равно NOT_AUTHORIZED (передается в нашей функции отклонения в функции разрешения), то мы перенаправляем пользователя на экран входа в систему для проверки подлинности.

ПРИМЕЧАНИЕ. В этой функции routeChangeError вы можете свободно делать то, что вам нравится, возможно, даже немного рычать, что пользователь не авторизован.

Другие вопросы по тегам