Javascript 通过双击防止创建两次帐户
我有一个应用程序,使用平均堆栈,最近我看到了一些奇怪的行为。现在这种情况并不是每次用户注册都会发生,到目前为止已经发生了3次。当用户注册时,应用程序将为该用户创建两个具有所有相同详细信息的帐户。现在,我已经添加了一些功能,可以检测用户是否已经存在该电子邮件,并将其重定向到登录页面,但似乎无法阻止该问题 这是我的密码:Javascript 通过双击防止创建两次帐户,javascript,node.js,express,passport.js,Javascript,Node.js,Express,Passport.js,我有一个应用程序,使用平均堆栈,最近我看到了一些奇怪的行为。现在这种情况并不是每次用户注册都会发生,到目前为止已经发生了3次。当用户注册时,应用程序将为该用户创建两个具有所有相同详细信息的帐户。现在,我已经添加了一些功能,可以检测用户是否已经存在该电子邮件,并将其重定向到登录页面,但似乎无法阻止该问题 这是我的密码: // ========================================================================= // LOCAL SIGN
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
firstNameField: 'firstName',
lastNameField: 'lastName',
usernameField: 'email',
passwordField: 'password',
jobTitleField: 'jobTitle',
startDateField: 'startDate',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({'email': email}, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, {
message: 'That email is already taken.'
});
}
else { var token = crypto.randomBytes().toString();
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.firstName = req.body.firstName;
newUser.lastName = req.body.lastName;
newUser.email = email;
newUser.password = newUser.generateHash(password); // use the generateHash function in our user model
newUser.jobTitle = req.body.jobTitle;
newUser.startDate = req.body.startDate;
newUser.birthday = req.body.birthday;
newUser.region = req.body.region;
newUser.sector = req.body.sector;
newUser.accountConfirmationToken = token;
newUser.accountConfirmationTokenExpires = Date.now() + 3600000;
newUser.accountVerified = 'false';
newUser.isLineManager = 'false';
// save the user
newUser.save(function(err) {
if (err)
throw err;
else {
var data = {
from: 'system',
to: email,
subject: 'Account Verification',
text: 'You recently registered onto the App, to gain access to your account please verify your account.\n\n' +
'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
'http://' + req.headers.host + '/verify/' + token + '\n\n'
};
mailgun.messages().send(data, function(error, body) {
console.log(body);
console.log("setting token 1");
req.flash('info', 'An e-mail has been sent to ' + email + ' with further instructions.');
});
return done(null, newUser);
}
});
}
});
}));
我的结论:
我通过创建一个测试帐户来测试应用程序,一旦我填写了注册表,我就快速地在“立即注册”按钮上单击两次,当我检查数据库时,它创建了两个具有相同详细信息的帐户。基本上,它会发送两个POST请求来创建帐户,并且这两个请求都会得到批准。当只有1个应被批准时
我的问题:
// configuration ===============================================================
mongoose.connect(database.url); // connect to mongoDB database on modulus.io
require('./config/passport')(passport);
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/views')); // set the static files location /public/img will be /img for users
app.use(busboy());
app.use(compression()); //use compression
app.use(morgan('dev')); // log every request to the console
app.use(bodyParser.urlencoded({'extended': true})); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use(methodOverride());
app.use(cookieParser()); // read cookies (needed for auth)
app.set('view engine', 'ejs'); // set up ejs for templating
// required for passport
app.use(session({ secret: ''})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
编辑:
路线代码:
app.post('/signup', function(req, res, next) {
passport.authenticate('local-signup', function(err, user, info) {
if (err) {
return next(err);
}
if (!user) {
return res.json({
message: 'An account with this email is already registered. Please try to login, if you cant remeber the password then please use our password reset service'
})
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
return res.json({
redirectUrl: '/verifyAccount',
message: 'We have sent an email to verify your email. Once you have verified your account you will be able to login'
});
});
})(req, res, next);
});
您可以在第一次按下时禁用注册按钮,以防止双击它 您可以在第一次按下时禁用注册按钮,以防止双击它
电子邮件
列上设置唯一约束
,这将不允许在现有电子邮件中插入行usernameField
,passwordField
(因此,您可以删除其他字段)。使用req.body
获取其他表单数据,就像您已经做的那样(以防重构)电子邮件
列上设置唯一约束
,这将不允许在现有电子邮件中插入行usernameField
,passwordField
(因此,您可以删除其他字段)。使用req.body
获取其他表单数据,就像您已经做的那样(以防重构)问题必须是由于node.js中的db异步操作造成的。检查您的流程,使用callback。您是否也可以发布您的
中间件
代码?(您的app.configure
block所在的位置)@DavidR您是指我的server.js
文件中配置整个应用程序的代码?或者调用本地注册
功能的中间件路由?我指的是服务器.js
,您在那里拥有所有应用程序配置。@DavidR请查看更新的问题,问题一定是由于与node.js中的db进行异步操作造成的。检查您的流程,使用callback。您是否也可以发布您的中间件
代码?(您的app.configure
block所在的位置)@DavidR您是指我的server.js
文件中配置整个应用程序的代码?或者调用本地注册
功能的中间件路由?我指的是服务器.js
,您在那里拥有所有应用程序配置。@DavidR请查看更新的问题是,但这并不能解决代码中的主要问题。我知道,那只是一种工作。我不知道nodejs,但我想到的唯一一件事是,当你的应用程序开始处理第一个请求或使用事务时,尝试锁定数据库写入是的,但这并不能解决代码中的主要问题。我知道,那只是一种工作。我不知道nodejs,但我想到的唯一一件事是,当应用程序开始处理第一个请求或使用事务时,尝试锁定数据库写入