req.isAuthenticated 无效

Posted

技术标签:

【中文标题】req.isAuthenticated 无效【英文标题】:req.isAuthenticated not worked 【发布时间】:2015-03-07 14:41:15 【问题描述】:

我正在开发一个 nodejs express 应用程序,我尝试使用带有电子邮件和密码的护照本地策略进行身份验证,但是在我成功登录后,当我检查 req.Authentication() 功能时,它给了我错误的值,所以请帮助我更正代码.

在我的 mvc/controller/user/index.js 文件中,当我签入 eports.auth 方法 consloe.log(req.user) 时,它显示了值,但在成功重定向后,我没有得到 req.user 成为空

我的应用结构是

 mvc(main folder)
 -------- db.js
 -------- index.js
 -------- package.json
 ----- conrollers (folder)
       -----user  (folder)
            ----- views (folder)
            ----- index.js (js file) 
 ----- lib (folder where middileware, router and other library file exist)
       --------- boot.js
 ----- models (folder)
       ------user.js
 ----- node-modules
 ----- passport(folder) 
       --------init.js
       --------login.js   
       --------signup.js
 ----- public (folder)
 ----- views (folder)
       --------4o4.ejs 
       --------5xx.ejs
       --------footer.ejs
       --------header.ejs

mvc/index.js

var express = require('./lib/express');
var logger = require('morgan');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var mongoose = require('mongoose');
var monk = require('monk');

var app = module.exports = express();

// settings
var dbConfig = require('./db');

//Connect to db
mongoose.connect(dbConfig.url);
var dbMonk = monk(dbConfig.url);

// set our default template engine to "jade"
// which prevents the need for extensions
app.set('view engine', 'ejs');

// set views for error and 404 pages
app.set('views', __dirname + '/views');

// Using the flash middleware provided by connect-flash to store messages in session
// and displaying in templates
/*var flash = require('connect-flash');
app.use(flash());*/
app.use(require('connect-flash')());
app.use(function (req, res, next) 
  res.locals.flashMessages = require('express-messages')(req, res);
  //console.log('res.locals.flashMessages : ');
  //console.log(res.locals.flashMessages);
  next();
);

// define a custom res.message() method
// which stores messages in the session
app.response.message = function(msg)
  // reference `req.session` via the `this.req` reference
  var sess = this.req.session;
  // simply add the msg to an array for later
  sess.messages = sess.messages || [];
  sess.messages.push(msg);
  return this;
;

// log
if (!module.parent) app.use(logger('dev'));

// serve static files
app.use(express.static(__dirname + '/public'));

// session support
app.use(session(
  resave: false, // don't save session if unmodified
  saveUninitialized: false, // don't create session until something stored
  secret: 'some secret here'
));

// parse request bodies (req.body)
app.use(bodyParser.urlencoded( extended: true ));

// allow overriding methods in query (?_method=put)
app.use(methodOverride('_method'));

// expose the "messages" local variable when views are rendered
app.use(function(req, res, next)
  var msgs = req.session.messages || [];

  // expose "messages" local variable
  res.locals.messages = msgs;
  console.log("res.locals.messages : ");
  console.log(res.locals.messages);
  // expose "hasMessages"
  res.locals.hasMessages = !! msgs.length;
  console.log("res.locals.hasMessages : ");
  console.log(res.locals.hasMessages);
  /* This is equivalent:
   res.locals(
     messages: msgs,
     hasMessages: !! msgs.length
   );
  */

  next();
  // empty or "flush" the messages so they
  // don't build up
  req.session.messages = [];
);

app.use(cookieParser());

//Configure Passport
var passport = require('passport');
app.use(passport.initialize());
app.use(passport.session());

// Initialize passport
var initPassport = require('./passport/init');
initPassport(passport);

// Make our db accessible to our router
app.use(function(req,res,next)
    req.db = dbMonk;
    next();
);

// Make our passport accessible to our router
app.use(function(req,res,next)
    req.passport = passport;
    next();
);

// load controllers
require('./lib/boot')(app,  verbose: !module.parent );

app.use(function(err, req, res, next)
  // log it
  if (!module.parent) console.error(err.stack);

  // error page
  res.status(500).render('5xx',title:"500 Error");
);

// assume 404 since no middleware responded
app.use(function(req, res, next)
  res.status(404).render('404',  url: req.originalUrl,title:"404 Page Not Found" );
);

/* istanbul ignore next */
if (!module.parent) 
  app.listen(3000);
  console.log('Express started on port 3000');

lib/boot.js

 /**
 * Module dependencies.
 */

var express = require('../lib/express');
var fs = require('fs');

module.exports = function(parent, options)
  var verbose = options.verbose;    
  fs.readdirSync(__dirname + '/../controllers').forEach(function(name)
    verbose && console.log('\n   %s:', name);
    var obj = require('./../controllers/' + name);
    var name = obj.name || name;
    var prefix = obj.prefix || '';
    var app = express();
    var handler;
    var method;
    var path;

    // allow specifying the view engine
    if (obj.engine) app.set('view engine', obj.engine);
    app.set('views', __dirname + '/../controllers/' + name + '/views');

    // generate routes based
    // on the exported methods
    for (var key in obj) 
      // "reserved" exports
      if (~['name', 'prefix', 'engine', 'before'].indexOf(key)) continue;
      // route exports
      switch (key) 
        case 'login':
          method = 'get',
          path = '/'+name+'/login';
          break;
        case 'logout':
          method = 'get',
          path = '/'+name+'/logout';
          break;
        case 'auth':
          method = 'post',
          path = '/'+name+'/login';
          break;
        case 'add':
          method = 'get',
          path = '/'+name+'/add';
          break;
        case 'save':
          method = 'post',
          path = '/'+name+'/save';
          break;
        case 'show':
          method = 'get';
          path = '/' + name + '/:' + name + '_id';
          //path = '/' + name + '/:id';
          break;
        case 'list':
          method = 'get';
          path = '/' + name + 's';
          break;
        case 'edit':
          method = 'get';
          path = '/' + name + '/:' + name + '_id/edit';
          break;
        case 'update':
          method = 'put';
          path = '/' + name + '/:' + name + '_id';
          break;
        case 'create':
          method = 'post';
          path = '/' + name;
          break;
        case 'index':
          method = 'get';
          path = '/';
          break;
        default:
          /* istanbul ignore next */
          throw new Error('unrecognized route: ' + name + '.' + key);
      

      // setup
      handler = obj[key];
      path = prefix + path;

      // before middleware support
      app[method](path, obj[key]);
      verbose && console.log('     %s %s -> %s', method.toUpperCase(), path, key);
      /*if (obj.before) 
        //app[method](path, obj.before, handler);
        app[method](path, obj[key]);
        verbose && console.log('     %s %s -> before -> %s', method.toUpperCase(), path, key);
       else 
        app[method](path, obj[key]);
        verbose && console.log('     %s %s -> %s', method.toUpperCase(), path, key);
      */

    

    // mount the app
    parent.use(app);
  );
;

控制器/用户/index.js

/**
 * Module dependencies.
 */
var bCrypt = require('bcrypt-nodejs');
var passport = require('passport');

//check authenticated method
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
  //console.log("req.user : ");console.log(req.session.user);
  //if (req.session.user) 
  if (req.isAuthenticated()) 
    console.log("Authenticated");
    return next();
  
  console.log("Not Authenticated");
  //if user is not authenticated then redirect him to the login page
  res.redirect('/user/login');


//add one more handler
exports.before = function(req, res, next)
  var id = req.params.user_id;
  //console.log(id);
  if (!id) return next();
  // pretend to query a database...
  process.nextTick(function()
    var db = req.db;
    var collection = db.get('user');
    collection.findOne("_id":id,,function(e,docs)
       if(e)
        console.log(e);
        else 
        req.user = docs;
        console.log(req.user);      
        
    );   

    // cant find that user
    if (!req.user) return next('route');
    // found it, move on to the routes
    next();
  );
;

//add user 
exports.add = function(req,res, next)
  res.render('add',title:"User Registration");

//login user
exports.login = function(req,res,next)
  res.render('login',title:"User Login");

//logout user
exports.logout = function(req,res,next)
    req.logout();
    //req.session.user = null;
    res.redirect('/user/login');

//login post
exports.auth = function(req,res,next)
  /*req.passport.authenticate('login',
            successRedirect: '/users/',
            failureRedirect: '/user/login',
            failureFlash : true
  )(req, res, next);*/
  passport.authenticate('login', function(err, user, info) 
    //console.log("userrrrrrrrrrrrrrrrrrrrrrrrrrrrr");
    //console.log(user);
    if (err)  return next(err); 
    if (!user)  return res.redirect('/user/login'); 
    req.logIn(user, function(err) 
      //console.log("user11111111111111111");
      //console.log(user);
      //console.log(req);
      console.log(req.isAuthenticated());
      if (err)  return next(err); 
      //console.log("ressssssssssssssssssssssssssss");
      //console.log(res);
      //req.session.user = req.user;
      //req.session.passport = req.user._id;
      return  res.redirect('/user/' + user._id);
    );
  )(req, res, next);  


//save user data
exports.save = function(req,res,next)
  /*var body = req.body;  
  db.users.push(name:body.user.name,pet:[],id:3);*/

    var db = req.db;     
    var userName = req.body.name;
    var userEmail = req.body.email;    
    var userPhone = req.body.phone;
    var userOldPassword = req.body.oldpassword;
    var userPassword = req.body.password;
    var userID = req.body.id;

    var collection = db.get('user');

    if (userID) 
      //if pwd is changed
      if((userOldPassword) && (userOldPassword != "")) 
          collection.findOne("_id":userID,"password":createHash(userOldPassword),,function(e,docs)
                if(e)
                  console.log(e);        
                 else 
                  //update user with new pwd
                  collection.update("_id":userID,"name":userName,"email":userEmail,"phone":userPhone,"password":createHash(userPassword) , function(err, result) 
                          if (err) 
                              // If it failed, return error
                              res.send("There was a problem updating the information to the database.");
                           else 
                              res.message('User Updated!'); 
                              // And forward to success page                   
                              res.redirect('/users/');  
                          
                    );        
                 
           ); 
       else 
          //update user without pwd
          collection.update("_id":userID,"name":userName,"email":userEmail,"phone":userPhone , function(err, result) 
                          if (err) 
                              // If it failed, return error
                              res.send("There was a problem updating the information to the database.");
                          
                          else 
                                res.message('User Updated!'); 
                                // And forward to success page                   
                                res.redirect('/users/');  
                          
                    );  
             
     else 
      collection.insert(
           "name":userName,
           "email":userEmail,
           "phone":userPhone,
           "password" : userPassword,
           "status" : "inactive",
           "created" : Date.now()
          , function (err, doc) 
              if (err) 
                   // If it failed, return error
                   res.send("There was a problem adding the information to the database.");
               else 
                   res.message('User Added!'); 
                   // If it worked, set the header so the address bar doesn't still say /adduser
                   //res.location("/users/");
                   // And forward to success page                   
                   res.redirect('/users/');                   
              
        );
    

//show user list
exports.list = function(req, res, next)
  console.log("req in +++++++++++++++++++++++++++=");
  console.log(req.user);
  //check authentication  
  isAuthenticated(req, res, next); 
  var db = req.db;
  var collection = db.get('user');
  collection.find(,,function(e,docs)
      if(e)
       console.log(e);
       else 
       console.log("user list : "+docs);
       res.render('list', "users" : docs, title: 'User List');
       
  );
  //res.render('list',  users: db.users, title : "Users List" );
;

exports.edit = function(req, res, next)
   var id = req.params.user_id;
  console.log(req.params.user_id);  
  var db = req.db;
  var collection = db.get('user');
    collection.findOne("_id":id,,function(e,docs)
       if(e)
        console.log(e);        
        else 
        res.render('edit',  user: docs ,  title : "Edit User");
        
  ); 

;

exports.show = function(req, res, next)
  console.log("??????????/??????");
  console.log(req.isAuthenticated());
  console.log(req.params["user_id"]);
  isAuthenticated(req, res, next);
  var id = req.params.user_id;
  console.log(req.params.user_id);  
  var db = req.db;
  var collection = db.get('user');
    collection.findOne("_id":id,,function(e,docs)
       if(e)
        console.log(e);        
        else 
        res.render('show',  user: docs, title : "Show User" );
        
  );     
;

exports.update = function(req, res, next)
  var body = req.body;
  req.user.name = body.user.name;
  res.message('Information updated!');
  res.redirect('/user/' + req.user.id);
;

// Generates hash using bCrypt
var createHash = function(password)
    return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null);

护照/init.js

var login = require('./login');
var signup = require('./signup');
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);


passport/login.js

var LocalStrategy   = require('passport-local').Strategy;
var User = require('../models/user');
var bCrypt = require('bcrypt-nodejs');

module.exports = function(passport)

    passport.use('login', new LocalStrategy(
            usernameField : 'email',
            passwordField : 'password',
            passReqToCallback : true
        ,
        function(req, email, password, done) 
            var db = req.db;
            var collection = db.get('user');            
            collection.findOne( 'email' :  email ,
                function(err, user) 
                    // In case of any error, return using the done method                    
                    if (err)
                        return done(err);
                    // Username does not exist, log the error and redirect back                    
                    if (!user)
                        console.log('User Not Found with email '+email);
                        //return done(null, false, req.flash('message', 'User Not found.'));
                        return done(null, false, req.flash('info', 'User Not found.'));                 
                    
                    console.log('check before valid password');
                    // User exists but wrong password, log the error 
                    if (!isValidPassword(user, password))
                        console.log('Invalid Password');
                        //return done(null, false, req.flash('message', 'Invalid Password')); // redirect back to login page
                        return done(null, false, req.flash('info', 'Invalid Password')); // redirect back to login page
                    
                    // User and password both match, return user from done method
                    // which will be treated like success                    
                    return done(null, user);
                
            );

        )
    );


    var isValidPassword = function(user, password)
        //console.log("Hashed Pwd : "+password);
        return bCrypt.compareSync(password, user.password);
    


【问题讨论】:

为什么不提供甚至更多的上下文? 【参考方案1】:

我自己解决了我使用时deserializeUser不能正常工作

passport.deserializeUser(function(id, done) 
        var collection = db.get('user');
        collection.findOne( '_id' :  id ,function(err, user) 
        //User.findById(id, function(err, user) 
           console.log('deserializing user:',user);
           done(err, user);
        );
    );

而不是

passport.deserializeUser(function(id, done) 
            User.findById(id, function(err, user) 
               console.log('deserializing user:',user);
               done(err, user);
            );
        );

我的 User.findById 函数不能正常工作!!!!!! :)

【讨论】:

但我遇到了另一个问题“错误:发送后无法设置标题。”两次我进入成功页面并检查身份验证。 "Can't set two headers after they are sent"意味着你可能在同一个请求中渲染一个页面两次(或更多)

以上是关于req.isAuthenticated 无效的主要内容,如果未能解决你的问题,请参考以下文章

req.isAuthenticated() 总是假的

Passport.js - req.isAuthenticated 不是一个函数

护照身份验证 req.isAuthenticated 始终为 false

Mean.js req.isAuthenticated 显示失败?

如何彻底销毁护照/快递会话?

使用 google-passport-oauth 登录后 req.user 未定义