Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pushing user data from Nodejs server to Angular after successful login

I try to login my user via Facebook with use of PassportJS and pass the user data to Angular. On the server side it all looks ok with the following code for the Facebook callback in users controller:

exports.facebookCallback = function() {
return function(req, res, next) {
    passport.authenticate('facebook', function(err, user, email) {
        if (err || !user) {
            return res.redirect('/auth');
        }
        req.login(user, function(err) {
            if (err) {
                return res.redirect('/auth');
            }
            return res.redirect('/');
        });
    })(req, res, next);
 };
};

From what I understand from the PassportJS docs, calling req.login should put user data into the session.

My routes on the server side looks following:

app.get('/auth', usersCtrl.auth);
app.get('/auth/signout', usersCtrl.logout);
app.get('/auth/facebook', passport.authenticate('facebook', {
    scope: ['email', 'user_hometown']
}));
app.get('/auth/facebook/callback', usersCtrl.facebookCallback());

express and passport configuration includes:

app.use(express.cookieParser());
app.use(express.session({secret: '1234567890QWERTY'}));
app.use(express.bodyParser());
app.use(passport.initialize());
app.use(passport.session());

Now on the angular side I try to get the user data from the session in a service defined like this:

module.exports = require('angular')
.module('HomeModule', [])
.controller('HomeCtrl', function ($scope) {
       //home controller code ors here
}).controller('NavbarCtrl', ['$scope', 'Authentication', function ($scope, Authentication) {
    $scope.authentication = Authentication;
    //rest of the navbar controller goes here
}]).factory('Authentication', [
    function() {
        var _this = this;

        _this._data = {
            user: window.user
        };

        return _this._data;

    }
]);

Unfoortunately, the user data is not available in window.user on angular side. Any ideas what I'm doing wrong here?

like image 588
Jakub Avatar asked Jun 21 '14 12:06

Jakub


2 Answers

As Girish said, the passport session object won't be available on client side. As you seem to be using express, a simple way to do this is to use express-expose.

If you want the user data to be available on all pages when the user is authenticated, you can add something like this before your routes declaration

app.use(function (req, res, next) {
    if (req.isAuthenticated()) res.expose(req.user, 'user');
    next ();
});

The user data will be available client side as window.user.

like image 74
WispyCloud Avatar answered Nov 01 '22 22:11

WispyCloud


The passport session object won't be available on the window object , instead you need to get it from the server using some service or a redirect url.

After successful authentication , the primary route function will be called, which, in this case, will redirect the user to the home page.

   app.get('/auth/facebook/callback', 
     passport.authenticate('facebook', { failureRedirect: '/login' }),
     function(req, res) {
     res.redirect('/');
   });


   app.get('/', function(req, res){
    res.render('index', { user: req.user });
   });

or you can create a route to get the logged in user data

   app.get('/account', function(req, res){
     if (req.isAuthenticated()) { 
       res.send({user : req.user}); 
     }else{
       res.redirect('/login');
     }
   });

On the Angular side, you can set the user data to rootscope from the $http response,

$rootScope.session = {}
$rootScope.session.user = res.user;
like image 35
Girish Avatar answered Nov 02 '22 00:11

Girish