即使login后,NodeJs Passport isAuthenticated()也会返回false

我是新来的angularJs,并尝试build立一个网站的本地身份validation。 我已经通过各种来源,这个https://vickev.com/#!/article/authentication-in-single-page-applications-node-js-passportjs-angularjs是非常有帮助的。 当我尝试在我的本地主机build立相同的代码进入一个循环。

app.post('/ login',…..)正在返回用户的响应,但在此之后加载pipe理页面,它正在检查用户是否通过调用app.get('/ loggedin',. ..)和req.isAuthenticated()即使在login后也返回false,并进入循环。 我不明白为什么这是发生plz帮助我。

服务器端代码

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')); }); 

客户端Js文件

 '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]); }); }); 

您需要允许在跨域中设置Cookie

快递

  res.header('Access-Control-Allow-Credentials', true); 

并在阿贾克斯设置

  xhrFields: { withCredentials: true } 

你可以在这里和这里find相关的答案

我认为rdegges是这个想法的一部分,因为cookies和会话variables是国家pipe理工作的一部分。 我认为bodyParser也是必需的,但我在这里省略了。

我在我的网站上使用Passport(对MongoDB用户表进行身份validation),这里是我的代码摘录。

/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'); } 

对于什么值得我没有看到你的isValidated()函数在任何地方定义。

可以是这么多的事情。

1.) PassportJS中的订单FacebookloginisAuthenticated返回false,即使身份validation成功 (在您的情况下,订单似乎是正确的)。

2.)没有req.login()和Passport和Passport一样local req.isAuthenticated总是返回false

在这种情况下,我select后者,但是出于与该问题不同的原因。 你已经提供了你自己的LocalStrategy 。 要使用户login,您必须自己调用req.login() 。 就像您将定义您自己的自定义callback一样,如passport文档中所述: http : //passportjs.org/guide/authenticate/ 。

你的浏览器保持你的会话cookie吗? 这听起来好像你的浏览器在login后没有保存你的会话cookie,这就是为什么后面的/loggedin请求失败。

忘记添加我也有同样的问题

 request.login() 

 app.post('/login', function(request, response, next) { console.log(request.session) passport.authenticate('login', function(err, user, info) { if(!user){ response.send(info.message);} else{ request.login(user, function(error) { if (error) return next(error); console.log("Request Login supossedly successful."); return response.send('Login successful'); }); //response.send('Login successful'); } })(request, response, next); } ); 

还要确保你有以下的初始化顺序

 var session = require('express-session'); // required for passport session app.use(session({ secret: 'secrettexthere', saveUninitialized: true, resave: true, // using store session on MongoDB using express-session + connect store: new MongoStore({ url: config.urlMongo, collection: 'sessions' }) })); // Init passport authentication app.use(passport.initialize()); // persistent login sessions app.use(passport.session()); 

在我的情况下,我尝试了JMeasbuild议的解决scheme来手动调用会话保存,但它不起作用

https://github.com/jaredhanson/passport/issues/482

 req.session.save(function() { successRedirect(); }) 

经过一些实验后,我只是将app.use(session({…}))移到所有中间件调用的顶部,现在req.isAuthenticated()按预期工作。 我想,会话设置应该作为第一个中间件,或者至less在设置cookie之前。

断线:

 var app = express(); app.use(query.json()); app.use(query.urlencoded({ extended: false })); app.use(cookies()); app.use(express.static(path.join(__dirname, 'public'))); app.use(passport.initialize()); app.use(passport.session()); app.use(session({ secret: 'card', resave: true, saveUninitialized: true })); app.use('/', routes); // this is where I call passport.authenticate() 

固定电话:

 app.use(session({ secret: 'card', resave: true, saveUninitialized: true })); app.use(query.json()); app.use(query.urlencoded({ extended: false })); app.use(cookies()); app.use(express.static(path.join(__dirname, 'public'))); app.use(passport.initialize()); app.use(passport.session()); app.use('/', routes);