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?
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
.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With