bob.mazzo
bob.mazzo

Reputation: 5637

Using resolve in ui-router to authenticate a user

I'm having a issue in my Angular app with regards to the resolve section of the ui-router. I'm trying to present a login modal the first time a user hits the website.

In my app.config.js, how do I inject my 'loginService':

angular
    .module('rage')
    .config(config);

function config($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise("/dashboard");
    $stateProvider
        .state('main', {
            url: "/dashboard",
            templateUrl: "app/views/dashboard.html",
            controller: 'MainCtrl',
            data: { pageTitle: 'RAGE', requireLogin: true },
            resolve: {

                 // *** WHERE DO I INJECT 'loginService' ? ***

                authUser: function () {
                    return loginService.loginModal().then(function (user) {
                        $rootScope.userID = user.userId;
                        userService.openUserSession(razorEnvJson).then(function (data) {
                            // assign some scope vars here..
                        });
                    })
                }
            }
        })
        .state('login', {
            url: "/login",
            templateUrl: "app/views/login-view.html",
            controller: 'LoginCtrl'
        })
}

loginService code:

(function () {
    'use strict';

    angular.module('rage').service('loginService',
        ['$rootScope', '$modal', 'datacontext', 'userService', login]);

    function login($rootScope, $modal, datacontext, userService) {
        var modalInstance = null
        
        this.loginModal = function(){
            modalInstance = $modal.open({
                animation: true,
                templateUrl: 'app/components/login/login.html',
                controller: 'LoginCtrl as login',      
            });            
            return modalInstance.result.then(function (user) {                
                return user;
            });
            
        };

    }
})();

LoginCtrl controller code:

(function () {
    'use strict';

    angular.module('rage').controller('LoginCtrl',
        ['$rootScope', '$scope', '$modalInstance', '$q', 'datacontext', 'userService', authenticate]);

    function authenticate($rootScope, $scope, $modalInstance, $q, datacontext, userService) {

        var login = this;

        // OK,CANCEL CLICK EVENTS FROM MODAL !!!
        $scope.ok = function () {
            //  var user = userService.authenticateWebUser();  // **** TBD ****              
            var user = {userId: login.userId, pswd: login.pswd};
            $modalInstance.close(user);
        };
        $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
        };

    }
})();

I've also attempted $rootScope.$on('$stateChangeStart' event inside app.js to transition the state from main to login, but that hangs up on me.

**** MY UPDATED APP.CONFIG.JS CODE, SEPT 18 ****

Here is the proper usage of resolve: using ui-router states.

function config($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/dashboard");
$stateProvider
.state('main', {
    url: "/dashboard",
    templateUrl: "app/views/dashboard.html",
    controller: 'MainCtrl',
    data: { pageTitle: 'RAGE', requireLogin: true },
    resolve: {
	authUser: ['$rootScope', 'loginService', 'userService', function ($rootScope, loginService, userService) {
	    return loginService.loginModal().then(function (user) {
		$rootScope.userID = user.userId;
		initSession(user, $rootScope, loginService, userService);	
	    })
	}]
    }
})
.state('login', {
    url: "/login",
    templateUrl: "app/views/login-view.html",
    controller: 'LoginCtrl'
})
}
function initSession(user, $rootScope, loginService, userService) {

    userService.getInitParams().then(function (envJson) {
        // some code omitted here...
	userService.openUserSession(envJson).then(function (data) {
	    var sessionID = data.data[0];
	    $rootScope.rageSessionVars.sessionID = sessionID;
	    $rootScope.rageSessionVars.userID = $rootScope.userID; // *** HOW TO SUSPEND ALL CODE UNTIL userID IS ASSIGNED ??? ***
	    console.log("sessionID = " + sessionID);

	    $rootScope.rageSessionVars.currDashboardName = "Default";
	});
           
    });

}

* MainCtrl controller code *

(function () {
    'use strict';
    angular.module('rage')
        .controller('MainCtrl',
            ['$rootScope', '$scope', '$interval', '$window', '$state', '$location', 'widgetDefinitions',
            'defaultWidgets', 'gadgetInitService', main]);

    function main($rootScope, $scope, $interval, $window, $state, $location, widgetDefinitions, defaultWidgets, gadgetInitService, authUser) {
        var main = this;
           
        **** authUser IS NEVER DEFINED !!!

        if ($scope.userID == undefined) {   /// *** NOTHING WORKS HERE !!! ***
            //$state.go('login');
            //$location.url('index.html#/?login');
            //return ;
        }

        if ($scope.userID == undefined) {
            main.userName = "risk user";
        }
        else {
            $scope.main.userName = $scope.userID;   
        }
    }
})();

Upvotes: 0

Views: 495

Answers (1)

Eilimint
Eilimint

Reputation: 307

Edit:

I see your getting confused on the use of 'Resolve'. It should be used when you want some data passed into the controller when it's being run. Not to run a function before initiating a controller.

This isn't what you really want in this situation.

It kinda depends on your authentication method, cookies/tokens etc. Here is a similar method that I would follow.

  • Have a Login service which handles the following -- Login/Logout of the user -- Checks if the user is authenticated

  • In your Controller call your service to check if the user is logged in. -- If the user is not logged in, then prompt login screen -- If the user is logged in, then let the controller continue execution

  • How I handle it, is whenever the user makes an UnAuthorised request where the server returns a 401 response I call my LoginService to prompt the login screen again.

  • I use an authInterceptor in Angular to catch any 401 response from the server. Here is a nice guide on it: http://onehungrymind.com/winning-http-interceptors-angularjs/

This allows you to write your Unauthorized handler in one place.

Hope that makes it a bit clearer.

Upvotes: 2

Related Questions