2016-08-03 2 views
0

У меня есть приложение, которое использует стек MEAN, недавно я увидел небольшое странное поведение. Теперь это происходит не каждый раз, когда пользователь регистрируется, до сих пор это произошло 3 раза. Когда пользователь регистрирует приложение, он создает 2 аккаунта для этого пользователя со всеми теми же деталями. Теперь я уже добавил функциональные возможности для обнаружения, если пользователь уже существует с этим адресом электронной почты и перенаправляет их на страницу входа, но, похоже, не останавливает проблему.Запретить создание учетной записи дважды с помощью двойного щелчка

Heres мой код:

// ========================================================================= 
// 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); 
        } 
       }); 
      } 

     }); 

    })); 

Мои выводы:

Я тестировал приложение, создав пробную учетную запись и один раз я заполнил форму регистрации, я быстро щелкнул дважды на signup-now, и когда я проверил базу данных, она создала 2 учетных записей с одинаковыми данными. В основном он отправляет 2 запроса POST для создания учетных записей, и оба они получают одобрение. Когда только 1 должен быть одобрен.

Мой вопрос:

  1. Как я могу решить эту проблему, так что если пользователь щелкает два раза на кнопку подключений это создает только одну учетную запись.

  2. Также может быть другая причина, по которой это может произойти, есть ли любая проблема с кодом выше?

Спасибо.

Edit:

App Config Код:

// 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 

Edit:

маршрут Код:

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); 
}); 
+1

Проблема должна быть из-за асинхронные операции с БД в Node.js. Проверьте поток, используйте обратные вызовы –

+0

Можете ли вы также отправить свой код «промежуточного кода»? (где у вас есть блок 'app.configure') –

+0

@DavidR Вы имеете в виду код в моем файле' server.js', где я настраиваю все приложение? или маршрута промежуточного программного обеспечения, который вызывает функцию «local-signup»? – Skywalker

ответ

2

Вы можете отключить кнопку Регистрация на первой пресс для предотвращения двойного щелчка по нему.

+0

Да, но это не устраняет основную проблему в коде. Это только работа. – Skywalker

+1

Я знаю. Я не знаю nodejs, но единственное, что приходит мне в голову, это попытаться заблокировать запись базы данных, когда ваше приложение начинает обрабатывать первый запрос или использовать транзакции. – theodorhanu

+0

обходные пути для меня отлично подходят для меня –

0
  1. В качестве решения я посоветую установить unique constraint на ваш email колонка, которая не будет позволять вставлять строки с существующей электронной почтой

  2. А что о коде, который использует LocalStrategy, его должен работать правильно, но вы можете просто переопределить usernameField, passwordField (Таким образом, вы можете удалить другие поля). Используйте req.body для того, чтобы получить другие данные формы, как вы уже сделали (Только в случае рефакторинга)