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 вы можете свободно делать то, что вам нравится, возможно, даже немного рычать, что пользователь не авторизован.