0

I want to authenticate states in my angular application. The resources that are available are too complicated and I don't understand why.

My simple logic is to set a variable

$rootScope.is_authenticated = true

and check whenever a state is loaded to see if the variable is true or not.

How can I achieve this and why is login and authentication so complicated in angular.

my config file

.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
    .state('auth', {
        url: '/auth',
        templateUrl: 'partials/auth.html',
        controller: 'AuthCtrl'
    })
    .state('dashboard', {
        url: '/dashboard',
        templateUrl: 'partials/dashboard.html',
        controller: 'DashboardCtrl',
        resolve:{
            check: function($rootScope, $state){
                if($rootScope.is_authenticated == true){
                    return true;
                }
                else{
                    $state.go('auth');
                }
            }
        }
    })

    $urlRouterProvider
    .otherwise("/auth");

login function in my AuthCtrl

//login
$scope.login = function(user){
    console.log(user);
    $http({
        method : "POST",
        url : "myapi.com/login",
        data : user
    }).then(function mySucces(response) {
        $scope.data = response.data;
        $rootScope.is_authenticated = true;
        $state.go('dashbooard');
    }, function myError(response) {
        $scope.error = response.statusText;
        $rootScope.is_authenticated = false;
    });
}

logout function

 $scope.logout = function(){
    $rootScope.is_authenticated = false;
    $state.go('auth');
}

I've added another property to my state, resolve. Now the state can only be accessed if the user is logged in. Is this the correct way and if not, what are the problems associated with it

1 Answer 1

1

I have achieved login, authentication by creating angular's run and service methods

My code snippet :

routes.js : // updating your code with authenticate key

.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
    .state('auth', {
        url: '/auth',
        templateUrl: 'partials/auth.html',
        controller: 'AuthCtrl'
    })
    .state('dashboard', {
        url: '/dashboard',
        templateUrl: 'partials/dashboard.html',
        controller: 'DashboardCtrl',
        authenticate: true // add this to the routes you want the users' should be authenticated
    })

    $urlRouterProvider.otherwise("/auth");

run.js :

(function () {
    'use strict';

    angular.module('app').run(runBlock);

    runBlock.$inject = ['$rootScope', '$state', '$log', 'AuthService'];

    function runBlock($rootScope, $state, $log, AuthService) {
        // detects change of state started
        var rootScopeOn = $rootScope.$on('$stateChangeStart', function (event, next, params) {
            // next.authenticate - if states needs to be authenticated
            if (next.authenticate && !$rootScope.currentUser) {
                event.preventDefault();


                if (AuthService.isLoggedIn()) {
                    AuthService.getLoggedInUser().then(function (response, status) {
                        $log.debug('Run - runBlock() - status : ', status);
                        if (!response) {
                            $state.go('login');
                        } else {
                            $state.go(next, params);
                        }
                    }, function () {
                        $log.error('Run - runBlock() : ERROR');
                        $state.go('login');
                    });
                } else {
                    $state.go('login');
                }
            }
        });
        $log.debug('Run - runBlock() - rootScopeOn : ', rootScopeOn);
    }
})();

auth.js :

(function() {
    'use strict';

    angular.module('app').factory('AuthService', AuthService);

    function AuthService($http, $q, $log, $rootScope, User) {
        function login(email, password) {
            // TODO : change the code here to consume your http post, I use ng-resource so code is according to that
            return User.login({ username: email, password: password }).$promise.then(function(response) {
                $rootScope.currentUser = {
                    id: response.user.id,
                    email: response.user.email,
                    userame: response.user.username,
                    emailVerified: response.user.emailVerified
                };
            });
        }

        function logout() {
            return User.logout().$promise.then(function() {
                $rootScope.currentUser = null;
            });
        }

        function isLoggedIn() {
            return User.isAuthenticated();
        }

        function getUserInfo() {
            return $rootScope.currentUser;
        }

        function setUserInfo(data) {
            $rootScope.currentUser = {
                id: data.id,
                role: data.role,
                email: data.email,
                userame: data.username,
                emailVerified: data.emailVerified
            };
        }

        function getLoggedInUser() {
            var deferred = $q.defer();
            User.getCurrent().$promise.then(function(response) {
                if(angular.isDefined(response.error)) {
                    if(response.error.status === 401) {
                        deferred.resolve(false);
                    }
                    else {
                        setUserInfo(response);
                        deferred.resolve(getUserInfo());
                    }
                }
                else {
                    setUserInfo(response);
                    deferred.resolve(getUserInfo());
                }
            });
            return deferred.promise;
        }

        function register(email, password) {
            return User.create({
                email: email,
                password: password
            }).$promise;
        }

        return {
            login: login,
            logout: logout,
            register: register,
            isLoggedIn : isLoggedIn,
            getUserInfo: getUserInfo,
            getLoggedInUser: getLoggedInUser
        };
    }
})();
Sign up to request clarification or add additional context in comments.

4 Comments

How do you persist the user or authentication if the page is refreshed?
When the page is refreshed, or url is copy-pasted in new tab : if (AuthService.isLoggedIn()) { AuthService.getLoggedInUser().then(function (response, status) { this code makes the server call again
I've updated the code, now its working for me. Could you check if its the correct way.
Assuming your whole app is wrapped with AuthCtrl, i don't think it should give problem, but what if user refreshes or copy-paste url in new tab, you can use cookie or seesions, i am using session storage to save user id and access token

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.