通过双击防止创建帐户两次

时间:2016-08-03 12:44:55

标签: javascript node.js express passport.js

我有一个使用MEAN堆栈的应用程序,最近我看到了一些奇怪的行为。现在每次用户注册时都不会发生这种情况,到目前为止它已经发生了3次。当用户注册应用程序时,为该用户创建具有所有相同详细信息的2个帐户。现在我已经添加了一些功能来检测用户是否已经存在该电子邮件并将其重定向到登录页面但似乎没有停止该问题。

继承我的代码:

package com.focusmedica.maadiabetes;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by windev on 8/2/2016.
 */

public class MainAdapter extends BaseAdapter implements Filterable {

ArrayList<DataModel> dataSet;
Context context;
DataModel content;
public ArrayList<DataModel> orig;

public MainAdapter(Context context, ArrayList dataSet) {
    super();
    this.context = context;
    this.dataSet = dataSet;
}


@Override
public int getCount() {
    return dataSet.size();
}

@Override
public Object getItem(int position) {
    return dataSet.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

class ViewHolder {
    private TextView tvChapterName;
    private ImageView ivChapterIcon;
}

@Override
public View getView(int position, View view, ViewGroup viewGroup) {
    final ViewHolder viewHolder;
    if (view == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.card_layout, null);
        viewHolder = new ViewHolder();
        viewHolder.tvChapterName = (TextView) view.findViewById(R.id.tvChapterName);
        viewHolder.ivChapterIcon=(ImageView)view.findViewById(R.id.ivChapterIcon);
        view.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) view.getTag();
    }
    content = dataSet.get(position);
    viewHolder.tvChapterName.setText(content.getChapterName());
    viewHolder.ivChapterIcon.setImageResource(R.drawable.caticon);
    return view;
}

public Filter getFilter() {
    return new Filter() {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            final FilterResults oReturn = new FilterResults();
            final ArrayList<DataModel> results = new ArrayList<>();
            final ArrayList<DataModel> ids = new ArrayList<>();
            if (orig == null)
                orig = dataSet;
            if (constraint != null) {
                if (orig != null && orig.size() > 0) {
                    for (final DataModel g : orig) {
                        if (g.getChapterName().toLowerCase().contains(constraint.toString())||
                                g.getChapterName().toUpperCase().contains(constraint.toString()))
                            results.add(g);
                    }
                }
                oReturn.values = results;
            }
            return oReturn;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                                      FilterResults results) {
            dataSet = (ArrayList<DataModel>) results.values;
            notifyDataSetChanged();
        }
    };
}

public void notifyDataSetChanged() {
    super.notifyDataSetChanged();
}
}

我的结论:

我通过创建测试帐户来测试应用程序,一旦我填写了注册表单,我就快速点击了两次在注册即时按钮上,当我检查数据库时,它创建了2个帐户相同的细节。基本上它发送2个POST请求来创建帐户,并且它们都被批准。只有1应该被批准。

我的问题:

  1. 如果用户在注册时点击两次,我该如何解决此问题 按钮它只创建一个帐户。

  2. 也可能有其他原因可能会发生,是吗?     上述代码的任何问题?

  3. 感谢。

    修改

    App Config Code:

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

    修改

    路线代码:

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

2 个答案:

答案 0 :(得分:2)

您可以在第一次按下时禁用注册按钮以防止双击它。

答案 1 :(得分:0)

  1. 作为一种解决方案,我建议您在<?php require_once("dbcontroller.php"); $db_handle = new DBController(); if(!empty($_POST["idprov"])) { $query ="SELECT * FROM kabupaten WHERE id_prov = '" . $_POST["idprov"] . "'"; $results = $db_handle->runQuery($query); ?> <option value="">Select State</option> <?php foreach($results as $kabupaten) { ?> <option value="<?php echo $kabupaten["id_kab"]; ?>"><?php echo $kabupaten["kabupaten"]; ?></option> <?php } } ?> 列上设置unique constraint,以便不允许插入包含现有电子邮件的行

  2. 那么使用LocalStrategy的代码如何,它应该可以正常工作,但您可以覆盖emailusernameField(因此,您可以删除其他字段)。使用passwordField以获取您已经完成的其他表单数据(仅在重构的情况下)