NodeJs Passport isAuthenticated()即使在登录后也返回false

时间:2014-10-28 07:20:31

标签: angularjs node.js authentication passport.js

我是Angular.js的新手并尝试为网站构建本地身份验证。我已经浏览了各种来源,Authentication in Single Page Applications非常有帮助。当我尝试在我的localhost中构建相同的代码时,我的代码进入循环。

app.post('/login',.....)在响应中返回用户,但在加载管理页面之后,它正在通过调用app.get('/loggedin',... )来检查用户是否已登录,并且req.isAuthenticated()正在返回{{1}即使在登录后它进入循环。我无法理解为什么会这样,请帮助我。

服务器端代码

false

客户端Js文件

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

6 个答案:

答案 0 :(得分:8)

您需要允许在跨域设置Cookie

快递

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

在ajax设置中

 xhrFields: {
     withCredentials: true
 }

您可以找到相关答案herehere

答案 1 :(得分:2)

我认为rdegges有一部分想法,因为cookie和会话变量是使状态管理工作的一部分。我认为bodyParser也是必需的,但我在这里省略了它。

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

/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()函数。

答案 2 :(得分:1)

可以这么多东西。

1。)PassportJS Facebook login isAuthenticated returns false even though authentication succeeds中的顺序(虽然在您的情况下顺序似乎正确)。

2。)没有Passport and Passport Local req.isAuthenticated always returns false

中的req.login()

在这种情况下,我选择后者,但原因与该问题不同。 您已提供自己的LocalStrategy。要让用户登录,您必须自己致电req.login()。就像您要定义自己的自定义回调一样,如passport文档中所述:http://passportjs.org/guide/authenticate/

答案 3 :(得分:0)

您的浏览器是否保留了会话Cookie?听起来好像您的浏览器在登录后没有抓住您的会话cookie,这就是后续/loggedin请求失败的原因。

答案 4 :(得分:0)

忘记添加

我遇到了同样的问题
request.login()

on

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

还要确保您有以下order进行初始化

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());

答案 5 :(得分:0)

在我的情况下,我尝试了JMeas建议的解决方案来手动调用会话保存,但它无法正常工作

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

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

经过一些实验,我只是将app.use(session({...}))移到所有中间件调用的顶部,现在req.isAuthenticated()按预期工作。我认为,会话设置应该作为第一个中间件或者至少在设置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);