nodejs中使用express和passport和mongodb的简单登录页面

Posted

技术标签:

【中文标题】nodejs中使用express和passport和mongodb的简单登录页面【英文标题】:Simple login page in nodejs using express and passport with mongodb 【发布时间】:2013-10-02 05:21:26 【问题描述】:

我在 /login 使用 Jade 和 Express 创建了一个简单的登录表单 表单数据通过 POST 发送到 /login

起初只是基于字符串的匹配(如果用户名== && 密码==)然后重定向到 /home 或重定向到 /login

简单。

现在我想将它的数据库驱动程序、用户名和密码存储在一个 mongodb 数据库中,匹配 db 中的用户名密码并进行处理。

我希望为此使用 passportJS,但我完全被它所震撼,从创建数据库到配置护照。

有人可以帮我制作一个简单的数据库驱动登录页面吗?我对nodejs的东西很陌生。 任何帮助将不胜感激

【问题讨论】:

【参考方案1】:

这是一个使用护照登录/注销用户的简单设置:

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

在您的用户模型上 (ej.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。我没有验证数据,但您应该在尝试保存用户之前对其进行验证。

【讨论】:

换句话说,它并不简单:p 鉴于创建一个工作应用程序需要 15 秒,我不明白您为什么给出了一个需要大量装配的半书面答案(对于新节点用户) .正如您可能已经猜到的那样,我是 node 新手,因此,我正在努力解决问题(很快,因为我有一个艰难的最后期限),所以我很难填补空白, 可以这么说。一个完整的例子将不胜感激。

以上是关于nodejs中使用express和passport和mongodb的简单登录页面的主要内容,如果未能解决你的问题,请参考以下文章

Passport + NodeJs + Express 得到“req.user”未定义

NodeJs Express passport-jwt 从令牌中获取错误的用户

phonegap ajax 用户身份验证与 nodejs-express-mongodb-passport js

如何在 Mongoose 中更新/更新文档/数据? Passport MongoDB、Express、AngularJS、Nodejs

没有使用 express 和 passport 设置 Cookie

Nodejs + Passport.js + Redis:如何在 Redis 中存储会话