0

我的网站由带有 html 的 Node.js 托管,当我从以下表单发布时:

 <form class="validateForm" id="registerform" method="POST" action="/signUp"  accept-charset='UTF-8'>
            <fieldset>
                <legend>Register</legend> <br>
                <input type="text" name="firstName" id="firstName" placeholder="First Name" maxlength="20" value=""/> <br>
                <input type="text" name="lastName" id="lastName" placeholder="Last Name" maxlength="20" value=""/> <br>
                <input type="text" name="email" id="email" placeholder="Email" maxlength="30" value=""/> <br>
                <input type="password" name="password" id="password" placeholder="Password" value=""/> <br>
                <input type="password" name="confirmPassword" id="confirmPassword"placeholder="Confirm Password" value=""/> <br>
                <input type="text" name="phoneNumber" id="phoneNumber" placeholder="Phone Number" maxlength="10" value=""/> <br>
                <input type="date" name="birthday" id="birthday" placeholder="Birthday" value=""/> <br>
                <label id="legalConfirm" for="agree"><input type="hidden" name="agree" value="0" /><input type="checkbox" name="agree" id="agree" value="1" checked="checked" /> By clicking join you confirm that you accept our <a href="/privacy.html">Privacy Policy</a> and <a href="/terms.html">Terms of Service</a>.</label>
                <input class="btn btn-primary" type="submit" name="create" value="Join"/>
                <a href="/"><button type="button" class="btn">Cancel</button></a>
            </fieldset>
        </form>

像这样运行连接到 mongoose 的 server.js 文件:

var express = require('express')
, home = require('./routes/home.js')
, path = require('path')
, http = require('http')
, bcrypt = require('bcrypt-nodejs')
, mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

var app = express();
app.get('/', home.index);
app.get('/signUp', home.signUp);
app.get('/about', home.about);
app.post('/signUp', home.signUpUser);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});

然后是路由器文件

var mongoose = require('mongoose');
var conn = mongoose.connection;
var bcrypt = require('bcrypt-nodejs');
var User = require('../models/user-model');
exports.signUpUser = function (req, res, next) {
if (req.body && req.body.email && req.body.password === req.body.confirmPassword) {
    var obj = new User ({
        firstName: req.body.firstName || 'na',
        lastName: req.body.lastName || 'na',
        email: req.body.email,
        password: req.body.password,
        phone: req.body.phoneNumber || '555-555-555',
        birthday: new Date(req.body.birthday) || new Date()
    });
console.log(conn.collection('users'));
    conn.collection('users').insert(obj, function (err) {
        if (!err) {
            res.redirect('/about.html');
        } else {
            next(err);
        }
    });
} else {
    next(new Error('Incorrect POST'));
}
};

然后是用户模型文件

var mongoose = require('mongoose'),
Schema = mongoose.Schema,
bcrypt = require('bcrypt-nodejs'),
SALT_WORK_FACTOR = 10;
 // these values can be whatever you want - we're defaulting to a
// max of 5 attempts, resulting in a 2 hour lock
MAX_LOGIN_ATTEMPTS = 5,
LOCK_TIME = 2 * 60 * 60 * 1000;

var UserSchema = new Schema({
email: { type: String, required: true, lowercase:true, index: { unique: true } },
password: { type: String, required: true },
firstName: {type: String, required: true},
lastName: {type: String, required: true},
phone: {type: Number, required: true},
birthday: {type: Date, required: true},


loginAttempts: { type: Number, required: true, default: 0 },
lockUntil: { type: Number }

});

 UserSchema.virtual('isLocked').get(function() {
// check for a future lockUntil timestamp
return !!(this.lockUntil && this.lockUntil > Date.now());
});


//password hashing middleware

UserSchema.pre('save', function(next) {
var user = this;

// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();

// generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
    if (err) return next(err);

    // hash the password along with our new salt
    bcrypt.hash(user.password, salt, function(err, hash) {
        if (err) return next(err);

        // override the cleartext password with the hashed one
        user.password = hash;
        next();
    });
});    
});
//password verification

UserSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
    if (err) return cb(err);
    cb(null, isMatch);
});
};


UserSchema.methods.incLoginAttempts = function(cb) {
// if we have a previous lock that has expired, restart at 1
if (this.lockUntil && this.lockUntil < Date.now()) {
    return this.update({
        $set: { loginAttempts: 1 },
        $unset: { lockUntil: 1 }
    }, cb);
}
// otherwise we're incrementing
var updates = { $inc: { loginAttempts: 1 } };
// lock the account if we've reached max attempts and it's not locked already
if (this.loginAttempts + 1 >= MAX_LOGIN_ATTEMPTS && !this.isLocked) {
    updates.$set = { lockUntil: Date.now() + LOCK_TIME };
}
return this.update(updates, cb);
};

// expose enum on the model, and provide an internal convenience reference 
var reasons = UserSchema.statics.failedLogin = {
NOT_FOUND: 0,
PASSWORD_INCORRECT: 1,
MAX_ATTEMPTS: 2
};

UserSchema.statics.getAuthenticated = function(username, password, cb) {
this.findOne({ username: username }, function(err, user) {
    if (err) return cb(err);

    // make sure the user exists
    if (!user) {
        return cb(null, null, reasons.NOT_FOUND);
    }

    // check if the account is currently locked
    if (user.isLocked) {
        // just increment login attempts if account is already locked
        return user.incLoginAttempts(function(err) {
            if (err) return cb(err);
            return cb(null, null, reasons.MAX_ATTEMPTS);
        });
    }

    // test for a matching password
    user.comparePassword(password, function(err, isMatch) {
        if (err) return cb(err);

        // check if the password was a match
        if (isMatch) {
            // if there's no lock or failed attempts, just return the user
            if (!user.loginAttempts && !user.lockUntil) return cb(null, user);
            // reset attempts and lock info
            var updates = {
                $set: { loginAttempts: 0 },
                $unset: { lockUntil: 1 }
            };
            return user.update(updates, function(err) {
                if (err) return cb(err);
                return cb(null, user);
            });
        }

        // password is incorrect, so increment login attempts before responding
        user.incLoginAttempts(function(err) {
            if (err) return cb(err);
            return cb(null, null, reasons.PASSWORD_INCORRECT);
        });
    });
});
};

module.exports = mongoose.model('User', UserSchema);

有什么问题会导致这种情况吗?我假设它可能是我的表单/路由器文件中未包含在用户模型文件中的内容。

此外,如果有人注意到安全代码在使用 Salt、hash/bcrypt 方面是否正确,那就太好了!

如果它是正确的,那么它应该在数据库中显示什么密码(null 或一些加密代码?)

4

1 回答 1

0

好的,所以我有一个比我了解更多的朋友。首先,我遗漏了一些内容,因为我正在查看一个带有旧版本 bcrypt 的示例,所以我不得不在这一行添加 null 而不是 progress

在 user-model.js 文件中

bcrypt.hash(user.password, salt, null, function(err, hash)

在路由器文件中我插入而不是保存,我在不需要的猫鼬连接上调用它

obj.save(函数(错误)

还从标题中删除了这些,不需要它们

var 猫鼬 = 要求('猫鼬');var conn = mongoose.connection;

密码确实也包含盐和哈希。

于 2013-05-26T03:22:11.117 回答