【问题标题】:angularjs : How to authenticate before route changesangularjs:如何在路由更改之前进行身份验证
【发布时间】:2013-12-03 10:28:34
【问题描述】:

如何在 angularjs 应用中的路由更改之前等待身份验证完成。

我正在使用 angularfire 简单身份验证。

My plunker is here

您可以使用 example@gmail.comexample 作为凭据来测试 plunker。

我知道问题的原因。但不知道怎么解决...

实际上,当经过身份验证的用户转到 '#/home/ 时,在 sahyiApp.run(function(){ ...}) 函数中会检查一个条件if(next.authRequired && !$rootScope.user){ ... } 。实际上经过身份验证的用户可以通过此检查,但是此代码在实际身份验证发生之前运行.. 那么有什么方法可以在路由更改之前进行身份验证...

【问题讨论】:

  • 你想达到什么目的还不清楚
  • 我认为这篇文章可能会对您有所帮助:stackoverflow.com/questions/14980805/… 在解析部分运行您对服务器的身份验证调用并返回承诺。在解决之前,路线不会改变。
  • 另外,请查看 angularFire-seed,其中包含使用 Firebase 登录的有效路由示例。
  • @Kato 谢谢。 angularFire-seed 对我来说是非常有用的资源。但在那里遇到同样的问题。如果登录用户转到localhost:63342/app/index.html#/account(在新窗口中,刷新页面)登录页面在显示帐户页面之前闪烁。

标签: angularjs firebase angularfire angular-routing


【解决方案1】:

更新

随着 angularFire 的发展,现在大部分内容已经过时了。查看此模块以获取更新版本:https://github.com/firebase/angularFire-seed/blob/master/app/js/module.simpleLoginTools.js

它装饰了ng-cloak 以使用简单的登录,并提供一些优化的帮助方法以及使用最新版本。

旧帖

身份验证需要往返服务器。在 SPA 中,您通常不会在正常使用期间重新加载页面,因此在大多数情况下这确实是多余的。

不过,只要对 Angular 有一定的了解,解决起来并不难。事实上,我在最近的一次研讨会上讲了这个确切的场景作为编写指令的示例。 Here's the gist I usedhere's an example app 使用要点。

请注意,如果您尝试克隆 GitHub 存储库,则需要获取该特定标签 (git checkout step3),因为该课程是分步教授的。

为了符合 SO 格式,这里是要点的内容。首先是指令:

angular.module('waitForAuth', [])

/**
 * A service that returns a promise object, which is resolved once angularFireAuth
 * is initialized (i.e. it returns login, logout, or error)
 */
.service('waitForAuth', function($rootScope, $q, $timeout) {
    var def = $q.defer(), subs = [];
    subs.push($rootScope.$on('angularFireAuth:login', fn));
    subs.push($rootScope.$on('angularFireAuth:logout', fn));
    subs.push($rootScope.$on('angularFireAuth:error', fn));
    function fn() {
       for(var i=0; i < subs.length; i++) { subs[i](); }
       $timeout(function() {
           // force $scope.$apply to be re-run after login resolves
           def.resolve();
       });
    }
    return def.promise;
})

/**
 * A directive that hides the element from view until waitForAuth resolves
 */
.directive('ngCloakAuth', function(waitForAuth) {
   return {
       restrict: 'A',
       compile: function(el) {
           console.log('waiting');
           el.addClass('hide');
           waitForAuth.then(function() {
               el.removeClass('hide');
           })
       }
   }
})

/**
 * A directive that shows elements only when the given authentication state is in effect
 */
.directive('ngShowAuth', function($rootScope) {
    var loginState;
    return {
        restrict: 'A',
        compile: function(el, attr) {
            var expState = attr.ngShowAuth;
            function fn(newState) {
                loginState = newState;
                el.toggleClass('hide', loginState !== expState );
            }
            fn(null);
            $rootScope.$on("angularFireAuth:login",  function() { fn('login') });
            $rootScope.$on("angularFireAuth:logout", function() { fn('logout') });
            $rootScope.$on("angularFireAuth:error",  function() { fn('error') });
        }
    }
});

以及一些示例用法:

<style>
  .hide { display: none; }
</style>

<script>
  // include the waitForAuth module as a dependency
  angular.module('myApp', ['waitForAuth'])

  // you can use waitForAuth directly from your scripts
  .controller('myController', function(waitForAuth) {
     waitForAuth.then(function() {
         /* do something after auth completes */
     })
  })
</script>

<!-- and you can use the directives in your views -->
<div ng-cloak-auth>Authentication has resolved.</div>

<div ng-show-auth="login">{{user.id}} is logged in</div>

<div ng-show-auth="logout">Logged out</div>

<div ng-show-auth="error">An error occurred during authentication</div>

【讨论】:

    猜你喜欢
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 2018-12-27
    • 2021-11-18
    相关资源
    最近更新 更多