使用angularjs http-auth和$ resource

时间:2013-09-13 00:14:36

标签: http authentication angularjs http-authentication

我正在努力使HTTP Auth Interceptor模块与$ resource一起工作。

现在,我有一个基本的应用程序使用这样的服务:

angular.module('myApp.services', ['ngResource']).
factory('User', function($resource){
    return $resource('path/to/json/', {}, { 'login': { method: 'GET' } });
});

然后像这样的控制器:

angular.module('myApp.controllers', []).
controller('User', ['$scope', 'User', function($scope, List) 
    {    $scope.user = User.query();
]);

和app:

angular.module('myApp', ['myApp.services', 'myApp.directives', 'myApp.controllers']).
config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/dashboard', {templateUrl: 'partials/dashboard.html', controller: 'Dashboard'});
    $routeProvider.when('/user', {templateUrl: 'partials/user.html', controller: 'TrackingCtrl'});
    $routeProvider.otherwise({redirectTo: '/dashboard'});
}]);

直到现在,一切都像预期的那样运作。然后,我在服务器上放了一个http auth,所以json文件的http状态是401,浏览器显示一个登录弹出窗口。我想使用HTTP Auth Interceptor模块替换浏览器登录弹出窗口并处理登录。这是这个脚本的目的吧?

为此,我尝试了解demo of the script并使用我的应用程序。

首先,我将'http-auth-interceptor'注入应用。

然后,这被添加到index.html

<body ng-controller="UserCtrl" class="auth-demo-application waiting-for-angular">

和ng-view上面的登录表单:

<div id="login-holder">
    <div id="loginbox">
        <div id="login-inner" ng:controller="LoginController">
             <form ng-submit="submit()">
                  Username: <input type="text" class="login-inp" ng-model="username"/><br/>
                  Password: <input type="password" class="login-inp" ng-model="password"/><br/>
                  <input type="submit" class="submit-login"/>
             </form>
        </div>
    </div>
</div>

和页面底部的脚本:

<script src="lib/directives/http-auth-interceptor.js"></script>

在controller.js中:

    controller('LoginController', ['$scope', 'authService', 'User', function ($scope, authService, User) {
    $scope.submit = function() {
        User.login( 
            function(user, response) { // success
                authService.loginConfirmed();
                console.log('login confirmed');
            }
        ); 
    }
}])

也是这个指令:

directive('authDemoApplication', function() {
    return {
        restrict: 'C',
        link: function(scope, elem, attrs) {
            //once Angular is started, remove class:
            elem.removeClass('waiting-for-angular');

            var login = elem.find('#login-holder');
            var main = elem.find('#content');

            login.hide();

            scope.$on('event:auth-loginRequired', function() {
                login.slideDown('slow', function() {
                    main.hide();
                });
            });
            scope.$on('event:auth-loginConfirmed', function() {
                main.show();
                login.slideUp();
            });
        }
    }
})

好的......就是这样。但它根本不起作用:浏览器登录表单仍然存在。这是唯一的登录方式。

我应该怎么做才能使这项工作?

1 个答案:

答案 0 :(得分:4)

从他们的网页:

典型用例:

  • 某处: $ http(...)。然后(函数(响应){do-something-with-response})被调用,
  • 该请求的响应是HTTP 401,
  • 'http-auth-interceptor'捕获初始请求并广播'event:auth-loginRequired',
  • 您的申请会截取此信息,例如:显示登录对话框(或其他任何内容),
  • 一旦您的申请表明身份验证没问题,您就可以致电: authService.loginConfirmed()
  • 您的初始失败请求现在将被重试,最后,做某事与响应将会触发。

因此,与此进行交互所需要做的唯一事情就是让父作用域听取even:auth-loginRequired。这可以在指令中完成,在控制器中,没关系。我没有使用过这个软件,但我想象的是这样的:

angular.module('myApp', [])
.service('api', function(httpAutenticationService, $rootScope, $location) {
  $rootScope.$on('event:auth-loginRequired', function() {
    // For the sake of this example, let's say we redirect the user to a login page
    $location.path('/login')
  })
  $http.get(API_URL).then( ... ); // If the user is not authenticated, this will be intercepted (1)
})
.controller('LoginController', function(httpAutenticationService) {
  // Let's imagine you have a route with the 'controller' option to this controller
  $http.get(LOGIN_URL).then(function() {
    httpAutenticationService.loginConfirmed(); // The success callback from (1) will be executed now
  }, function(){
    alert("Invalid credentials")
  })
})