【问题标题】:using angularjs http-auth with $resource使用 angularjs http-auth 和 $resource
【发布时间】:2013-09-13 00:14:36
【问题描述】:

我正在尝试使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();
]);

和应用程序:

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 Module 来替换浏览器登录弹出窗口并处理登录。这是这个脚本的目的,对吧?

为此,我试图了解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();
            });
        }
    }
})

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

对我应该做些什么来完成这项工作有任何想法吗?

【问题讨论】:

    标签: http authentication angularjs http-authentication


    【解决方案1】:

    来自他们的网页:

    典型用例:

    • 在某处调用:$http(...).then(function(response) { do-something-with-response })
    • 该请求的响应是 HTTP 401,
    • “http-auth-interceptor”捕获初始请求并广播“event:auth-loginRequired”,
    • 您的应用程序将其拦截到例如显示登录对话框(或其他),
    • 一旦您的应用程序确定身份验证正常,您将调用:authService.loginConfirmed()
    • 现在将重试您最初失败的请求,最后,do-something-with-response 将触发。

    因此,与此交互所需要做的唯一事情就是拥有一个父范围来收听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")
      })
    })
    

    【讨论】:

    • 感谢您的回答。但是这个解决方案使用$http,我不确定它是如何与$resource 以及我上面描述的应用程序结构交互的。你觉得呢?
    • 你可以用$resource,没关系。我的观点是,您唯一需要的就是在一定范围内监听事件event:auth-loginRequired。如果您想在指令中使用它(您需要在链接过程中使用范围变量(例如var linkFn = function(scope, element, attrs) { scope.$on(...)}。请注意,控制器在链接过程之前执行,因此除非您通过指令执行请求,否则您的监听器可能已关闭。
    • 很抱歉我的回答迟了,但是……嗯……我仍然对此感到困惑。来自示例文件:$http.post('data/protected', $scope.restrictedData).success(function(response) { // this piece of code will not be executed until user is authenticated $scope.restrictedContent.push(response); }); 据我了解,此脚本可以与 $resource 一起使用(因为它取决于 $http),但结果必须传入每个 $resource 方法的成功回调。还是我错过了重点?
    • 是的,那是正确的。如果您从服务器收到 401 响应,来自 $resource$http 的成功回调会以某种方式存储,然后在/如果用户进行身份验证时执行。
    • 好的。我更新了我上面的帖子,做了一些修改。但它仍然无法正常工作。就像没有被截获一样……浏览器原生弹出窗口总是在这里并且正在工作,但是我的登录表单什么也没做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 2016-11-08
    相关资源
    最近更新 更多