使用Express和Passport以及MongoDB创建Node.js的简单登录页面

10

我使用Jade和Express创建了一个简单的登录表单位于/login,表单数据通过POST方法发送到/login。

一开始只是基于字符串匹配(如果用户名== && 密码==),然后重定向到/home或重定向到/login。

很简单。

现在我想将其改为数据库驱动,将用户名和密码存储在mongodb数据库中,从数据库中匹配用户名和密码并执行相应操作。

我希望使用passportJS来实现,但我完全卡在了这里,无从下手,从创建数据库到配置passport都不会。

有谁能帮帮我,告诉我如何制作一个简单的数据库驱动登录页面?我对nodejs还非常陌生。任何帮助都将不胜感激。

1个回答

27

这里是使用passport进行用户登录/注销的简单设置示例:

在主要的 app.js 文件中

/* Auth config  --------------------------------*/
// @see http://frederiknakstad.com/authentication-in-single-page-applications-with-angular-js/

var passport = require('passport');
var User = require('./app/models/User'),

passport.use(User.localStrategy);
passport.serializeUser(User.serializeUser);
passport.deserializeUser(User.deserializeUser);

// Default session handling. Won't explain it as there are a lot of resources out there
app.use(express.session({
    secret: "mylittlesecret",
    cookie: {maxAge: new Date(Date.now() + 3600000)}, // 1 hour
    maxAge: new Date(Date.now() + 3600000), // 1 hour
    store: new RedisStore(config.database.redis), // You can not use Redis 
}));

// The important part. Must go AFTER the express session is initialized
app.use(passport.initialize());
app.use(passport.session());

// Set up your express routes
var auth = require('./app/controllers/authController.js');

app.post('/auth/login', auth.login);
app.post('/auth/logout', auth.logout);
app.get('/auth/login/success', auth.loginSuccess);
app.get('/auth/login/failure', auth.loginFailure);

在你的用户模型上(例如 app/models/User.js)

我正在使用 passport-local 模块,它进一步简化了登录逻辑:https://github.com/jaredhanson/passport-local

/* Your normal user model      ----------------------*/
var mongoose = require('mongoose'),
    ObjectId = mongoose.Schema.Types.ObjectId,
    PassportLocalStrategy = require('passport-local').Strategy;

var schema = new mongoose.Schema({
    name: {type:String, required:true, trim:true},
    email: {type:String, required: true, trim: true, lowercase:true, unique: true},
    image: {type:String},
    password: {type:String, required: true },
    created: {type: Date, default: Date.now}
});

/* Auth properties      ---------------------------*/
/* (passport)           ---------------------------*/

// This is your main login logic
schema.statics.localStrategy = new PassportLocalStrategy({
        usernameField: 'email',
        passwordField: 'password',
    },

    // @see https://github.com/jaredhanson/passport-local
    function (username, password, done){
        var User = require('./User');
        User.findOne({email: username}, function(err, user){
            if (err) { return done(err); }

            if (!user){
                return done(null, false, { message: 'User not found.'} );
            }
            if (!user.validPassword(password)){
                return done(null, false, { message: 'Incorrect password.'} );
            }

            // I'm specifying the fields that I want to save into the user's session
            // *I don't want to save the password in the session
            return done(null, {
                id: user._id,
                name: user.name,
                image: user.image,
                email: user.email,
            });
        });
    }
);

schema.methods.validPassword = function(password){
    if (this.password == password){
        return true;
    }

    return false;
}

schema.statics.serializeUser = function(user, done){
    done(null, user);
};

schema.statics.deserializeUser = function(obj, done){
    done(null, obj);
};

var model = mongoose.model('User', schema);

exports = module.exports = model;

在app/controllers/authController.js中

我正在使用单页面应用程序,因此在登录/注销时返回JSON。如果您想要重定向到其他地方,则必须修改“登录成功”和“登录失败”函数(或调用res.render(...)或其他函数)。

var passport = require('passport');
var AuthController = {

    // Login a user 
    login: passport.authenticate('local', {
        successRedirect: '/auth/login/success',
        failureRedirect: '/auth/login/failure'
    }),

    // on Login Success callback
    loginSuccess: function(req, res){
        res.json({
            success: true,
            user: req.session.passport.user
        });
    },

    // on Login Failure callback
    loginFailure: function(req, res){
        res.json({
            success:false, 
            message: 'Invalid username or password.'
        });
    },

    // Log out a user   
    logout: function(req, res){
        req.logout();
        res.end();
    },

};

exports = module.exports = AuthController;

最后,你需要将登录表单(需要设置method="post"属性)指向/auth/login。登录成功时,“loginSuccess”回调将被执行。登录失败时,“loginFailure”回调将被执行。

编辑:

你可以通过执行以下类似的操作在mongo数据库中创建新用户:

// On your main app.js file
app.post('/auth/register', auth.register);

// On your authController.js file, as per the previous example
var User = require('./app/models/User'); // The model we defined in the previous example    

...
register: function(req, res){
    User.create({name: req.body.name, email: req.body.email, password: req.body.password}, function(err){
      if (err) {
        console.log(err);
        ... // Your register error logic here
        res.redirect('/* Your error redirection path */');
        return;
      }

      res.redirect('/* Your success redirection path */'); 
    });
},
...

接下来,将注册表单指向/auth/register。我没有对数据进行验证,但在尝试保存用户之前,您应该验证它。


7
换句话说,这并不简单 :p。 - Jamie Hutber
考虑到你只需要15秒钟就能创建一个工作的应用程序,我不明白为什么你会给出一个半成品答案,需要很多调整(对于新的Node用户来说)。正如你所猜测的那样,我是Node的新手,因此我正在尝试快速解决问题(因为我有一个紧急的截止日期),所以对我来说填补空白非常困难。如果能提供一个完整的示例,将不胜感激。 - dylnmc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接