Meteor: check email does not exist in Meteor.users collection before creating an account

送分小仙女□ 提交于 2019-12-24 04:18:16

问题


I have a form where users enter their email address and password into a join form. This creates the account but I now want to develop it further.

client.js:

Template.joinForm.events({
    'submit .form-join': function(e, t) {
        e.preventDefault();
        var email = t.find('#email').value,
        password = t.find('#password').value,
        username = Random.id(),
        array = [],
        profile = {
            nameOfArray: array
        };
        Accounts.createUser({
            email: email,
            username: username,
            password: password,
            profile: profile
        }, function(error) {
            if (error) {
                alert(error);
            } else {
                Router.go('/');
            }
        });
    }
});

Before creating a user account, how do you:

  1. Check if the email variable from the joinForm does not already exist in the Meteor.users collection. Processing this on the server?

  2. If email does exist, then reject user creation?

I have seen the new function and wondering if I can use this http://docs.meteor.com/#/full/accounts_validatenewuser

Accounts.validateNewUser(function (user) {
    // pseudo if statement code
    if (email not exist) {
        // 1. create the user account and then
        Accounts.sendVerificationEmail(userId, [email])
    } else {
        throw new Meteor.Error(403, "email address is already registered");
    }
});

Thank you for reading this.

I'm unclear as to whether to use Accounts.createUser or Accounts.onCreateUser and which code should be on the client, and which on the server. My aim is to build the account securely, therefore, deny any other modification privileges during this process from the console.


回答1:


The extra empty array nameOfArrayis now created on the server if the account is allowed to be created, ie, passing the validateNewUser function. Of course, you can add more validation checks for example, password length.

client.js:

Template.joinForm.events({
    'submit .form-join': function(e, t) {
        e.preventDefault();
        var email = t.find('#email').value,
            password = t.find('#password').value,
            username = Random.id();
        Accounts.createUser({
            email: email,
            username: username,
            password: password,
            profile: profile
        }, function(error) {
            if (error) {
                alert(error.reason);
            } else {
                Router.go('/');
            }
        });
    }
});

server.js:

Accounts.onCreateUser(function(options, user) {
    var newEmail = user.emails[0].address;
    console.log(newEmail);
    var emailAlreadyExist = Meteor.users
        .find({"emails.address": newEmail}, {limit: 1})
        .count() > 0;
    console.log(emailAlreadyExist + ' already exists');
    if (emailAlreadyExist === true) {
        throw new Meteor.Error(403, "email already registered");
    } else {
        profile = options.profile;
        profile.nameOfArray = [];
        user.profile = profile;
        return user;
    }
});



回答2:


I've found that Accounts.createUser has it's own validation built in and checks for already existing email/login.

Meteor docs: Accounts.createUser:

If there are existing users with a username or email only differing in case, createUser will fail.

Thus Accounts.onCreateUser doesn't even fire if Accounts.createUser email/login validation throws error.




回答3:


The Accounts.validateNewUser function requires users to validate their email after submitting. It's basically that step where, after you sign up for something, before you can sign in you have to enter a code that's sent to you on your email or mobile device -- basically, it ensures that the user is who they say they are. It's what might prevent you from signing up with the email totallyfake@totally_not_a_real_place.com.

If I'm reading your question right, you're more interested in seeing if an email is unique than in seeing if the user actually owns that email account. You can do this with Accounts.onCreateUser, which runs on the server:

Called whenever a new user is created. Return the new user object, or throw an Error to abort the creation.

The full process will look something like this. On the client, exactly what you have:

Template.joinForm.events({
'submit .form-join': function(e, t) {
    e.preventDefault();
    var email = t.find('#email').value,
        password = t.find('#password').value,
        username = Random.id(),
        array = [],
        profile = {
            nameOfArray: array
        };

    Accounts.createUser({
        email: email,
        username: username,
        password: password,
        profile: profile
    }, function(error) {
        if (error) {
            alert(error);
        } else {
            Router.go('/');
        }
    });
    }
});

Then, on the server, before the user is actually created, it will run the user through your onCreateUser function, and whatever you return will be inserted into the users collection:

Accounts.onCreateUser(function(options, user) { 
  var email = user.emails[0];
  if (!email) { throw new Meteor.Error("You must provide a non-empty email"); // this may actually not be necessary -- createUser might do it for you
  if (Meteor.users.find({emails: email}) { 
    throw new Meteor.Error("A user with email " + email + " already exists!"); 
  }

  ... // whatever other transformation you might want
  return user; 
});

You might also check out the accounts-ui package, since depending on how much you want to do vary from a vanilla implementation of user accounts, a lot may already be done for you.




回答4:


The Accounts.validateNewUser is used to check if the fields of the user object comply with the desired format, returning true or false accordingly.

To check if the email is already registered, I think you should include this verification in the Accounts.onCreateUser function (http://docs.meteor.com/#/full/accounts_oncreateuser).

Without having tested the code, you can try something like this:

Accounts.validateNewUser(function (user) {
     // Check compliance of the user object fields, using check http://docs.meteor.com/#/full/check
});

Accounts.onCreateUser(function(options, user) {
       if (options.profile){
          user.profile = options.profile;
       }

       if (Meteor.users.find({email: user.email}).fetch == 0) {
           if(Accounts.validateNewUser(user)){
                Accounts.sendVerificationEmail(userId, [email]);
                return user;
           } else {
               throw new Meteor.Error(403, "Error checking user fields");
       } else {
         throw new Meteor.Error(403, "email address is already registered");
       }       
 }     


来源:https://stackoverflow.com/questions/29253983/meteor-check-email-does-not-exist-in-meteor-users-collection-before-creating-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!