AngularJS 使用新的 Firebase Auth 进行路由和解析
AngularJS Routes and Resolve with new Firebase Auth
我正在尝试将新的 Firebase 与 Auth 系统一起使用,并通过 resolves
在我的 $routeProvider
中限制路由。
不过,我不是很明白。
这就是我的。在我的 .config 函数中,我正在定义路由并初始化 firebase。以下是我的配置块。
$routeProvider
.when('/', {
templateUrl: 'templates/dashboard.ejs',
//resolve. this needs restricted
})
.when('/login', {
templateUrl: 'templates/login.ejs'
})
firebase.initializeApp(config);
我在新文档站点上发现这些功能可用,这些功能列在我的 .run()
区块中 angular。
.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。
所以我的问题是,我如何获取我的 .运行() 函数中的内容并将其转化为我的 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();
}]
}
})
然后是.运行()块中的routechangeerror.
// .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
returns null 当没有用户被验证时?
所以我不确定它是否是全球最简洁的代码,但它确实有效。
Firebase 现在提供了一项新功能,用于对当前用户进行身份验证(如果有的话)。初始化 firebase 后,您可以访问此功能。 firebase.auth().currentUser
。
(此函数 returns 如果已登录则为用户详细信息,如果未登录则为空)
因此,在您的路线中,您将根据此函数的结果创建和解决承诺。请务必将 deferred 定义为 $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'(在 resolve 函数中传递给我们的拒绝函数),那么我们会将用户重定向到登录屏幕以进行身份验证。
注意:在这个 routeChangeError 函数中,您可以自由地做任何您喜欢的事情,甚至可以显示用户未被授权的小咆哮。
这些方法已重命名为 $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 与 Auth 系统一起使用,并通过 resolves
在我的 $routeProvider
中限制路由。
不过,我不是很明白。
这就是我的。在我的 .config 函数中,我正在定义路由并初始化 firebase。以下是我的配置块。
$routeProvider
.when('/', {
templateUrl: 'templates/dashboard.ejs',
//resolve. this needs restricted
})
.when('/login', {
templateUrl: 'templates/login.ejs'
})
firebase.initializeApp(config);
我在新文档站点上发现这些功能可用,这些功能列在我的 .run()
区块中 angular。
.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。
所以我的问题是,我如何获取我的 .运行() 函数中的内容并将其转化为我的 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();
}]
}
})
然后是.运行()块中的routechangeerror.
// .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
returns null 当没有用户被验证时?
所以我不确定它是否是全球最简洁的代码,但它确实有效。
Firebase 现在提供了一项新功能,用于对当前用户进行身份验证(如果有的话)。初始化 firebase 后,您可以访问此功能。 firebase.auth().currentUser
。
(此函数 returns 如果已登录则为用户详细信息,如果未登录则为空)
因此,在您的路线中,您将根据此函数的结果创建和解决承诺。请务必将 deferred 定义为 $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'(在 resolve 函数中传递给我们的拒绝函数),那么我们会将用户重定向到登录屏幕以进行身份验证。
注意:在这个 routeChangeError 函数中,您可以自由地做任何您喜欢的事情,甚至可以显示用户未被授权的小咆哮。
这些方法已重命名为 $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) {
}