Question

I am trying to make HTTP Auth Interceptor Module work together with $resource.

for now, i have a basic app working with services like this :

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

and then controllers like this one :

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

and the 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'});
}]);

Until now, everything is working like expected. Then, i put an http auth on the server, so the json files http status are 401 and the browser display a login popup. I would like to use the HTTP Auth Interceptor Module to replace the browser login popup and handle the login. it is the purpose of this script, right ?

To do so, i am trying to understand the demo of the script and make that work with my app.

first, i injected 'http-auth-interceptor' to the app.

then, this was added to index.html

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

and the login form above 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>

and the script at the bottom of the page:

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

in 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');
            }
        ); 
    }
}])

and this directive too :

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();
            });
        }
    }
})

Ok… that's it. but it's not working at all: the browser loggin form is still there. and that's the only way to login.

any idea on what i should do to make this work ?

Was it helpful?

Solution

From their webpage:

Typical use case:

  • somewhere the: $http(...).then(function(response) { do-something-with-response }) is invoked,
  • the response of that requests is a HTTP 401,
  • 'http-auth-interceptor' captures the initial request and broadcasts 'event:auth-loginRequired',
  • your application intercepts this to e.g. show a login dialog (or whatever else),
  • once your application figures out the authentication is OK, you are to call: authService.loginConfirmed(),
  • your initial failed request will now be retried and finally, the do-something-with-response will fire.

So the only thing you need to do to interact with this is to have a parent scope to listen to even:auth-loginRequired. This can be done in a directive, in a controller, it doesn't matter. I haven't used the software, but I'm imagining something like this:

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")
  })
})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top