NodeJs Passport isAuthenticated() returning false even after login
Solution 1
You need to allow cookies to be set in cross domain
In express
res.header('Access-Control-Allow-Credentials', true);
And in ajax setup
xhrFields: {
withCredentials: true
}
You can find relevant answers here and here
Solution 2
I think rdegges has part of the idea since cookies and session variables are part of what makes the state management work. I think that bodyParser is also required but I omitted it here.
I'm using Passport on my website (authenticating to a MongoDB users table) and here are excerpts from my code.
/server.js:
var cookieParser = require('cookie-parser');
...
var passport = require('passport');
var expressSession = require('express-session');
var initPassport = require('./passport/init');
initPassport(passport);
...
self.app.use(cookieParser());
self.app.use(expressSession({secret: 'MYSECRETISVERYSECRET', saveUninitialized: true, resave: true}));
self.app.use(passport.initialize());
self.app.use(passport.session());
...
var routes = require('./routes/index')(passport);
self.app.use('/', routes);
/passport/init.js:
var login = require('./login');
var signup = require('./register');
var User = require('../models/user');
module.exports = function(passport) {
// Passport needs to be able to serialize and deserialize users to support persistent login sessions
passport.serializeUser(function(user, done) {
console.log('serializing user: ');
console.log(user);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
console.log('deserializing user:', user);
done(err, user);
});
});
// Setting up Passport Strategies for Login and SignUp/Registration
login(passport);
signup(passport);
}
/routes/index.js:
var passport = require('passport');
var User = require('../models/user');
...
var isAuthenticated = function (req, res, next) {
// if user is authenticated in the session, call the next() to call the next request handler
// Passport adds this method to request object. A middleware is allowed to add properties to
// request and response objects
if (req.isAuthenticated())
return next();
// if the user is not authenticated then redirect him to the login page
res.redirect('/login');
}
For what it's worth I'm not seeing your isValidated() function anywhere defined.
Solution 3
Can be so many things.
1.) Order as in PassportJS Facebook login isAuthenticated returns false even though authentication succeeds (order seems correct though in your case).
2.) No req.login() as in Passport and Passport Local req.isAuthenticated always returns false
In this case I opt for the latter but for a different reason than in that question.
You have provided your own LocalStrategy
. To make the user log in, you will have to call req.login()
yourself. Just as if you would define your own custom callback, as described in the passport
documentation: http://passportjs.org/guide/authenticate/.
Related videos on Youtube
Kumar teja
Updated on July 12, 2022Comments
-
Kumar teja almost 2 years
I'm new to Angular.js and trying to build local authentication for a website. I have gone through various sources and Authentication in Single Page Applications was very helpful. When I tried build the same in my localhost my code went in to a loop.
app.post('/login',.....)
is returning user in the response but after that while loading the admin page it is checking whether the user is logged in by callingapp.get('/loggedin',... )
andreq.isAuthenticated()
is returningfalse
even after login and it goes to a loop. I can't understand why this is happening please help me.Server Side code
var express = require('express'); var http = require('http'); var path = require('path'); var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; //================================================================== // Define the strategy to be used by PassportJS passport.use(new LocalStrategy( function(username, password, done) { if (username === "admin" && password === "admin") // stupid example return done(null, {name: "admin"}); return done(null, false, { message: 'Incorrect username.' }); } )); // Serialized and deserialized methods when got from session passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(user, done) { done(null, user); }); // Define a middleware function to be used for every secured routes var auth = function(req, res, next){ if (!req.isAuthenticated()) res.send(401); else next(); }; //================================================================== // Start express application var app = express(); // all environments app.set('port', process.env.PORT || 3000); app.use(express.favicon()); app.use(express.cookieParser()); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.session({ secret: 'securedsession' })); app.use(passport.initialize()); // Add passport initialization app.use(passport.session()); // Add passport initialization app.use(app.router); app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); // development only if ('development' == app.get('env')) { app.use(express.errorHandler()); } //================================================================== // routes app.get('/', function(req, res){ res.render('index', { title: 'Express' }); }); app.get('/users', auth, function(req, res){ res.send([{name: "user1"}, {name: "user2"}]); }); //================================================================== //================================================================== // route to test if the user is logged in or not app.get('/loggedin', function(req, res) { res.send(req.isAuthenticated() ? req.user : '0'); }); // route to log in app.post('/login', passport.authenticate('local'), function(req, res) { res.send(req.user); }); // route to log out app.post('/logout', function(req, res){ req.logOut(); res.send(200); }); //================================================================== http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port')); });
Client Side Js file
'use strict'; /********************************************************************** * Angular Application **********************************************************************/ var app = angular.module('app', ['ngResource','ngRoute']) .config(function($routeProvider, $locationProvider, $httpProvider) { //================================================ // Check if the user is connected //================================================ var checkLoggedin = function($q, $timeout, $http, $location, $rootScope){ // Initialize a new promise var deferred = $q.defer(); // Make an AJAX call to check if the user is logged in $http.get('http://localhost:3000/loggedin').success(function(user){ // Authenticated if (user !== '0') $timeout(deferred.resolve, 0); // Not Authenticated else { $rootScope.message = 'You need to log in.'; $timeout(function(){deferred.reject();}, 0); $location.url('/login'); } }); return deferred.promise; }; //================================================ //================================================ // Add an interceptor for AJAX errors //================================================ $httpProvider.responseInterceptors.push(function($q, $location) { return function(promise) { return promise.then( // Success: just return the response function(response){ return response; }, // Error: check the error status to get only the 401 function(response) { if (response.status === 401) $location.url('/login'); return $q.reject(response); } ); } }); //================================================ //================================================ // Define all the routes //================================================ $routeProvider .when('/', { templateUrl: 'views/main.html' }) .when('/admin', { templateUrl: 'views/admin.html', controller: 'AdminCtrl', resolve: { loggedin: checkLoggedin } }) .when('/login', { templateUrl: 'views/login.html', controller: 'LoginCtrl' }) .otherwise({ redirectTo: '/login' }); //================================================ }) // end of config() .run(function($rootScope, $http){ $rootScope.message = ''; // Logout function is available in any pages $rootScope.logout = function(){ $rootScope.message = 'Logged out.'; $http.post('http://localhost:3000/logout'); }; }); /********************************************************************** * Login controller **********************************************************************/ app.controller('LoginCtrl', function($scope, $rootScope, $http, $location) { // This object will be filled by the form $scope.user = {}; // Register the login() function $scope.login = function(){ $http.post('http://localhost:3000/login', { username: $scope.user.username, password: $scope.user.password, }) .success(function(user){ // No error: authentication OK $rootScope.message = 'Authentication successful!'; $location.url('/admin'); }) .error(function(){ // Error: authentication failed $rootScope.message = 'Authentication failed.'; $location.url('/login'); }); }; }); /********************************************************************** * Admin controller **********************************************************************/ app.controller('AdminCtrl', function($scope, $http) { // List of users got from the server $scope.users = []; // Fill the array to display it in the page $http.get('http://localhost:3000/users').success(function(users){ for (var i in users) $scope.users.push(users[i]); }); });
-
Ben Orozco about 9 yearsWhy wouldn't the browser keep the cookie? It's suppose to be its default behavior!
-
rdegges about 9 yearsThis can happen for many reasons: eg, when the cookie is set it's set with an expirey time.