我目前正在开发API。我正在使用Strongloop(Loopback)。
我正在尝试为用户注册时实施电子邮件验证。我有一个"用户"扩展内置"用户"模型。
现在,当用户注册(POST / users)时,会发送一封电子邮件,其中包含指向/ users / confirm的链接,其中包含三个适当的参数,即uid,重定向和令牌。当用户点击该链接时,后者的电子邮件地址已正确验证(email验证字段变为true)。
但是,我注意到在/ users上发出POST请求时,响应中包含验证令牌。这是正常的吗?验证令牌是否只能通过发送的电子邮件进行访问?
因为实际上,通过在/ users上发出POST请求并在响应中获取验证令牌,可以轻松地向用户发送另一个请求/使用适当的参数(包括验证令牌)进行确认并验证电子邮件即使地址不存在也要处理。
我是Strongloop的新手,也许我错过了一些东西。你们能帮忙吗?
答案 0 :(得分:4)
答案 1 :(得分:2)
如果你想创建用户注册验证链接但不使用内置用户现代,那么你需要创建验证令牌然后发送link.i已经添加了两个方法。你需要使用带有一个参数的远程方法谁是对象类型:您需要使用注册邮箱发送参数。方法是这样的....这里我们使用user =任何变量名,modelN =模型名称
modelN.sendVerificationEmail = function (data, callback) {
var user = loopback.models.modelN;
if (!data.email) {
return callback(commonUtils.buildError(
'Recipient email is required.', 400, 'EMAIL_REQUIRED'
));
}
if (!emailValidator.validate(data.email)) {
return callback(commonUtils.buildError(
'Must provide a valid email.', 400, 'INVALID_EMAIL'
));
}
var findOneuserPromise
= modelN.findOne({ 'where': { 'email': data.email }});
findOneBusinessEmployeePromise.then(function (user) {
if (!user) {
return callback();
}
var sendVerificationEmailPromise
= anothermodelname.sendVerificationEmail(user.id);
sendVerificationEmailPromise.then(function () {
callback();
});
sendVerificationEmailPromise.then(null, function (error) {
callback(error);
});
});
findOneuserPromise.then(null, function (error) {
callback(error);
});
};
我添加了另一个模型模型方法然后添加它,....
anothermodelname.sendVerificationEmail = function (userid) {
var modelN = loopback.models.modelN;
var Email = loopback.models.Email;
var deferred = Q.defer();
var findByIduserPromise = modelN.findById(userId);
findByIduserPromise.then(function (user) {
if (!user) {
return deferred.reject(commonUtils.buildError(
'Unknown "modelN" id "' + userId + '".',
404, 'MODEL_NOT_FOUND'
));
}
if (!user.verificationToken) {
return deferred.resolve(true);
}
modelN.generateVerificationToken(user,
function (verificationTokenError, verificationToken) {
if (verificationTokenError) {
return deferred.reject(verificationTokenError);
}
user.verificationToken = verificationToken;
var saveuserPromise = user.save();
saveuserPromise.then(function (updateduser) {
var link = emailConf.clientBaseUrl +
emailConf.verifyEmailRedirect + '?uid=' +
updateduser.id + '&token=' +
updateduser.verificationToken;
console.log("check+link:",link);
/*eslint camelcase: [0, {properties: "never"}]*/
emailOptions.to = updateduser.email;
emailOptions.template = { 'name': 'verify' };
emailOptions.global_merge_vars = [];
emailOptions.global_merge_vars.push({
'name': 'USER_NAME',
'content': updateduser.name
|| updateduser.username || updateduser.email
});
emailOptions.global_merge_vars.push({
'name': 'LINK',
'content': link
});
Email.send(emailOptions, function () {});
deferred.resolve(true);
});
saveuserPromise.then(null, function (error) {
deferred.reject(error);
});
});
});
findByIduserPromise.then(null, function (error) {
deferred.reject(error);
});
return deferred.promise;
};
答案 2 :(得分:1)
@ user2483431,验证电子邮件会将响应中的电子邮件验证令牌与用户ID一起公开。正如您所指出的那样,它可能会欺骗系统。一种解决方案是从响应中剥离令牌值。
在用户创建的afterRemote中,您可以使用
user.verify(options, function(err, response, next2) {
if (err) {
// error handling code
}
// stripping off verificationToken from response for security
var replacementText = "check email"
context.result.verificationToken = replacementText;
next();
});
希望这有帮助!