首页 > 解决方案 > Node JS Express、Passport JS 和 Android 设备身份验证问题

问题描述

  1. 我目前正在使用 Passport 的本地策略通过 Node JS Express 和 Passport 实现登录页面:http : //www.passportjs.org/packages/passport-local/
  2. 该数据库正在使用 MongoDB。
  3. 正在发生的问题是我无法在具有User A的 android 手机和 android 平板电脑上成功登录(有时我可以,但不一致)。
  4. 返回的响应是 401(未经授权的错误)。
  5. 我已经验证我可以在台式计算机上与用户 A一致地成功登录,并且还验证了我可以在 iOS 设备(iPhone 和 iPad)上登录。

有没有人有任何建议,和/或知道问题是什么?

下面是执行身份验证的代码

app_api/config/passport.js

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongoose = require('mongoose');
var User = mongoose.model('User');

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

passport.use(new LocalStrategy({
    usernameField: 'email'
  },
  function(username, password, done) {
    User.findOne({ email: username }, function (err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, {
          message: 'Incorrect username.'
        });
      }
      if (!user.validPassword(password)) {
        return done(null, false, {
          message: 'Incorrect password.'
        });
      }
      return done(null, user);
    });
  }
));

app_api/controllers/authentication.js

var passport = require('passport');
var mongoose = require('mongoose');
var User = mongoose.model('User');

var sendJSONresponse = function(res, status, content) {
  res.status(status);
  res.json(content);
};

module.exports.test = function(req, res) {
  sendJSONresponse(res, 200, { 'status' : 'success' });
};

module.exports.register = function(req, res) {
  if(!req.body.name || !req.body.email || !req.body.password) {
    sendJSONresponse(res, 400, {
      "message": "All fields required"
    });
    return;
  }

  var user = new User();

  user.name = req.body.name;
  user.email = req.body.email;

  user.setPassword(req.body.password);
  user.setShowResume(false);

  user.save(function(err) {
    var token;
    if (err) {
      sendJSONresponse(res, 404, err);
    } else {
      token = user.generateJwt();
      sendJSONresponse(res, 200, {
        'token' : token
      });
    }
  });

};

module.exports.login = function(req, res) {
  if(!req.body.email || !req.body.password) {
    sendJSONresponse(res, 400, {
      'message': 'All fields required'
    });
    return;
  }

  passport.authenticate('local', function(err, user, info){
    var token, showResume;

    if (err) {
      sendJSONresponse(res, 404, err);
      return;
    }

    if(user){
      token = user.generateJwt();
      showResume = user.showResume;
      sendJSONresponse(res, 200, {
        'token' : token,
        'showresume': showResume
      });
    } else {
      sendJSONresponse(res, 401, info);
    }
  })(req, res);
};

module.exports.logout = function(req, res) {
 req.logout();
 res.redirect('/');
};

下面是控制器 app_server/controllers/index.js 和调用 app_api/controllers/authentication.js 文件的函数logincontinue及其函数login

app_server/controllers/index.js

var request = require('request');

var apiOptions = {
  server : "http://localhost:3000"
};

if (process.env.NODE_ENV === 'production') {
  apiOptions.server = "https://siteDomain.com";
}

module.exports.home = function(req, res) {
    renderLoginPage(req, res);
};

/* Other routes / functions ... */

module.exports.logincontinue = function(req, res) {
    var path = '/api/authentication/login', sess;
    //var connectSid = res.req.cookies['connect.sid'];

    var requestOptions = {
        url : apiOptions.server + path,
        method : "POST",
        json : { email: req.body.username, password: req.body.password }/*,
        headers : { 'set-cookie':  connectSid }*/
    };

    request(requestOptions, function(err, response, body) {
        if(err) {
            renderPage(req, res, 'siteDomain.com', 'loginerror');
        } else if(response.statusCode === 200) {
            switch(body.showresume) {
                case true:
                    res.render('loginsuccessresume', {  title: 'siteDomain.com', page: 'loginsuccessresume', showresume: true });
                    break;
                default: 
                    renderPage(req, res, 'siteDomain.com', 'loginsuccess');
                    break;
            }
        } else if(response.statusCode === 401) {
            res.render('loginunauthorized', {  title: 'siteDomain.com', page: 'loginunauthorized', errormessage: body.message });
        } else {
            renderPage(req, res, 'siteDomain.com', 'loginerror');
        }
    });    
};

var renderPage = function(req, res, titleValue, pageValue) {
    res.render(pageValue, {  title: titleValue, page: pageValue });
};

var renderLoginPage = function(req, res) {
    res.render('index', { title: 'siteDomain.com', page: 'login' });
};

标签: javascriptnode.jsmongodbexpressmongoose

解决方案


  1. 作为更新,此问题已得到解决。
  2. 该问题与用户名字段的大小写敏感有关。
  3. 将 req.body.username 更改为 req.body.username.toLowerCase() 解决了app_server/controllers/index.js和函数logincontinue中的问题。

谢谢你。


推荐阅读