javascriptangularjsnode.jsauthenticationsatellizer

"Get Authenticated" loops forver on initial startup


Whenever I first load up my AngularJS application, I get a blank screen and this attempt to check if the user is authenticated in a never-ending loop.

For this project, I am using sails version 0.11.0, the newest version of AngularJS for frontend stuff, and Bower and Yeoman (specifically generator-cg-angular yeoman generator). I am also using satellizer, which is supposed to be helping tremendously with the process.

I am just setting up my first login and registration functionality, so I may have made some simple mistakes.

UPDATE: From some helpful people on the Sails Gitter chat room, I think that "a response isn’t being sent somewhere" -- what I was told was the likely cause of the error, from a pretty experienced developer. So that could be my issue.... don't know yet, just keeping this question updated.

Some of my relevant code is as follows:

This is the first state my application tries to send the user to (in app.js file):

$stateProvider.state('dashboard', {
    url: '/',
    templateUrl: 'partial/scaffold/scaffold.html',
    controller: 'ScaffoldCtrl as scaffold',
    data: { loginRequired: true } // will also apply to all children of 'dashboard'
});

These are the contents of my dashboard.auth service, which I know is critical in getting the authorization to work.

var currentUser,
    isAuthenticated = false,
    baseAuth = Restangular.all('user');

return {

    login: function (credentials) {
        return baseAuth.customPOST(credentials, 'login').then(function (user) {
            $log.debug('User logged in: ', user);
            isAuthenticated = true;
            return user;
        });
    },

    logout: function () {
        return baseAuth.customPOST({}, 'logout').then(function () {
            currentUser = undefined;
            isAuthenticated = false;
        });
    },

    register: function (newUser) {
        return baseAuth.customPOST(newUser, 'register').then(function (user) {
            isAuthenticated = true;
            return user;
        });
    },

    currentUser: function () {
        return currentUser;
    },

    isAuthenticated: function (force) {
        var deferred = $q.defer();

        if (isAuthenticated && currentUser) {
            deferred.resolve(currentUser);
        } else {
            return baseAuth.customGET('authenticated').then(function (user) {
                deferred.resolve(currentUser);
                isAuthenticated = true;
                currentUser = user;
                return user;
            });
        }

        return deferred.promise;
    }
};

Backend controllers:

Register

register: function (req, res) {
    RegistrationService.registerUser(req.body, function (err, user) {
        if (err) { res.json(400, err); }
        return res.json(user);
    });
},

Login

login: function (req, res) {
    passport.authenticate('user', function (err, user, info) {
        if (err) { return res.json(err); }
        else if (user) {
            req.logIn(user, function (err) {
                if (err) { return res.json(err); }
                return res.json(user);
            });
        } else { return res.json(400, info); }

    })(req, res);
},

Then there is a lot of different code on the backend, which all should be pretty standard, I tried to follow the best practices I found out there from tutorials. Let me know if you have any idea what is going on with my application.

Here is the error logged to the console when I go to http://localhost:9001/#/ where the app is running (it goes on and on and on in a loop...).

[Array[0], "get", "authenticated", "http://localhost:1337/user/authenticated"] angular.js:12314 ["", "get", "authenticated", "http://localhost:1337/user/authenticated"] angular.js:12314 [Array[0], "get", "authenticated", "http://localhost:1337/user/authenticated"] angular.js:12314 ["", "get", "authenticated", "http://localhost:1337/user/authenticated"] angular.js:12314 [Array[0], "get", "authenticated", "http://localhost:1337/user/authenticated"] angular.js:12314 ["", "get", "authenticated", "http://localhost:1337/user/authenticated"] angular.js:12314 [Array[0], "get", "authenticated", "http://localhost:1337/user/authenticated"]


Solution

  • Okay, I changed the controllers in the API, and the app.js file in the frontend. So the problem was somewhere in one of those.

    I believe the real issue was in the backend logic though.

    I went for a major simplification... and it worked.

    Changed the register action to:

    register: function (req, res) {
        User.create(req.body, function (err, user) {
            if (err) { next(err); }
            return res.json(user);
        });
    },
    

    Changed the login action to:

    login: function (req, res, next) {
        User.findOne( { email: req.body.email }, function (err, user) {
            if (err) { return next(err); }
            if (user) {
                bcrypt.compare(req.body.password, user.password, function (err, valid) {
                    if (err) { next(err); }
                    if (valid) {
                        req.session.userAuthenticated = true;
                        req.session.authenticated = true;
                        req.session.User = user;
                        return res.json({
                            message: "Logged in"
                        });
                    }
                });
            } else { next({ message: "Could not find a user with email " + req.body.email }); }
        });
    },
    

    That seems to have done the trick.