Angularjs在使用身份验证时路由波动

时间:2013-09-04 15:04:34

标签: javascript authentication angularjs angular-ui-router

我正在寻找一种更好的方法来在angularjs中进行路径状态之间的转换。目前,我一直在使用几个不同的教程来使用服务器端的身份验证来配置后端api服务器的角度。

http://frederiknakstad.com/authentication-in-single-page-applications-with-angular-js/ https://vickev.com/#!/article/authentication-in-single-page-applications-node-js-passportjs-angularjs

这两者都描述了与服务器端而不是客户端身份验证相同的解决方案。我有一个角度的Auth服务,它使用一种方法发布到api服务器,检查用户是否使用api密钥登录。

isLoggedIn: function( event, toState ) {
        var user_api = {};

        if( "user" in $rootScope ) {
            user_api = { "api": $rootScope.user.api };
        } 

        $http.post('http://bac-api/authenticated/', user_api)
            .success( function( user ) {
                if( toState.url === '/login' && user.authenticated === true) {
                    $state.transitionTo('dashboard');
                }
            })
            .error( function( user ) {
                if( user.authenticated === false ) {
                    event.preventDefault();
                    $state.transitionTo('login');
                }
            });
    },

如果当前不存在api密钥,则用户未登录,服务器将发送{“authenticticated”:false} 401响应。如果用户有api密钥,它使用该api密钥检查服务器是否有效(登录)或无效(未登录)。

为了捕获路由并检查用户是否经过身份验证我并使用“stateChangeStart”

$rootScope.$on("$stateChangeStart", function ( event, toState, toParams, fromState, fromParams ) {

    Auth.isLoggedIn( event, toState );

});  

这样做的第一个问题是在初始页面加载时没有触发状态更改,导致使用routeProvider转换到登录页面。然后在整个应用程序中,如果请求的路由不在配置的路由中,它将转换到登录页面但不会触发stateChangeStart。因此,用户可以登录并坐在登录页面上。我宁愿它作为我配置的路线转移到仪表板。

在大多数情况下,这种设置似乎在理论上工作正常,但路线不稳定。因此,在检查用户是否登录路由将开始更改并开始显示页面之间会发生什么,然后当应用程序意识到用户未被记录时,它将切换到登录页面。我想解决这个不稳定的问题。而不是让其他页面的格式能够正确传输。

我正在使用ui-router并在应用程序中声明一切。然后使用Route Provider仅在没有所请求路线的路线时执行$ routeProvider.otherwise('login')。

  1. 我想弄清楚如何在应用程序检查用户进行身份验证时,在路由转换期间停止显示部分新页面(不连贯)。这是否是我不知道的不同事件或其他事件。

  2. 使用routeProvider.otherwise()来触发状态更改并检查用户是否为LoggedIn的更好方法。如果登录转移到仪表板,如果没有登录则停留在登录页面上,直到完成登录。

  3. 很抱歉,如果这太令人困惑了。我是angularjs的新手,并且一直在阅读有关路线,状态和身份验证的所有内容。这是我学习如何使用angular管理服务器端身份验证的新概念。

    - 编辑

    在接受MBielski的推荐之后,我已经将状态解析为使用Auth.isLoggedIn()服务。但是这仍然没有消除切换路线的波动,我甚至担心一旦这不在局部发展中,那么在api响应等待时,波动会变得更糟。这是我的父仪表板状态的解析代码。

    'dashboard-shell': {
                name: 'dashboard-shell',
                resolve: {
                    Auth: function( Auth ) {
                        return Auth.isLoggedIn();
                    }
                },
                views: {
                  "dashboard-shell": {
                    controller: 'DashboardController',
                    templateUrl: 'app/modules/template-manager/partials/dashboard.tpl.html'
                  }
                }
            },
    

2 个答案:

答案 0 :(得分:4)

您的问题似乎是每次状态更改都会导致POST请求必须处理才能切换状态。我假设您这样做是为了处理会话到期,或者因为您没有要检查的身份验证cookie。

您基本上实现了悲观方法,以确保在执行任何其他HTTP回调之前对用户进行身份验证。

另一种方法可能是使用angular-http-auth HTTP拦截器。这个拦截器提供了一个乐观方法来确保用户被认证:它只是将每个HTTP调用传递给后端,但是你给它一个特殊的回调;当后端返回403 Unauthorized时,此回调用于例如显示登录对话框,以便用户可以(重新)进行身份验证。之后,拦截器重放导致403的所有HTTP调用。

答案 1 :(得分:0)

ui-router有一个解决方案,可以清除印章。 https://github.com/angular-ui/ui-router/wiki。解决部分中包含的任何内容都将在其余路由更改发生并加载页面之前完全解析。

isLoggedIn: function( event, toState ) {
    var user_api = {};

    if( "user" in $rootScope ) {
        user_api = { "api": $rootScope.user.api };
    } 

    return $http.post('http://bac-api/authenticated/', user_api);
},

resolve: {
   var logged = Auth.isLoggedIn();
   logged.then(function(data){
       //success
   }, function(data){
      //failure
   });
}