我想知道如何创建一个方法,或者是否有一种方法可以仅使用电子邮件生成新 token 。我想在我的网站“发送新的验证电子邮件”中创建一个选项,用户只需要输入电子邮件即可。实际上我正在使用 Mandril,所以我使用自定义方式发送电子邮件和验证用户:
function generateVerificationToken(context, user, callback) {
const { req } = context;
req.app.models.User.generateVerificationToken(user, (error, token) => {
if (error) {
return callback(error, null);
}
callback(null, token);
});
}
User.afterRemote('create', (context, user, next) => {
generateVerificationToken(context, user, (error, token) => {
if (error) {
return next(error);
}
user.verificationToken = token;
user.save((error) => {
if (error) {
return next(error);
}
loopback.Email.send({
to: user.email,
template: {
name: 'signup-confirm',
},
global_merge_vars: [{
name: 'href',
content:`http://localhost:3000/api/accounts/confirm?uid=${user.id}&token=${token}&redirect=http://localhost:4200/login/token-verification&verification=1`
}]
}, (error) => {
next(error);
});
});
});
});
提前致谢!
最佳答案
(注意:这个问题有点棘手,因为它涉及一些修改,虽然不是那么难,但可能需要对代码进行一些重构。另外,请参阅最后的警告说明。)
1.覆盖用户模型
(注意:尽管您可以在另一个模型中执行此操作,但为了保持一致性,我发现最好在 User
中执行此操作,即使还有更多工作要做。)
要覆盖 User 模型,您可以做两件事。有些人喜欢添加一个新的user
模型(小写)并在那里进行覆盖,但我个人更喜欢使用 Spencer Mefford's more elegant way of doing it .
您应该检查整个要点,因为还有很多事情要做,但总结一下,您需要创建一个新的启动脚本,最好以“0”开头的名称(启动脚本按字母顺序执行,因此您需要在其他东西之前准备好模型),例如
server/boot/0-user-model-override.js
然后添加必要的样板:
module.exports = function (app) {
var User = app.models.User;
var Email = app.models.Email;
var Role = app.models.Role;
var RoleMapping = app.models.RoleMapping;
var ACL = app.models.ACL;
/*
* If this is an initial setup, create the ACL entry,
* otherwise just configure the relationships
* (this needs to be done every time the server is started)
*/
if(process.env.INIT_SETUP == "true"){
ACL.create({
model: 'User',
property: 'customEndpoint1',
accessType: 'EXECUTE',
principalType: 'ROLE',
principalId: '$everyone',
permission: 'ALLOW'
}, function (err, acl) { // Create the acl
if (err) console.error(err);
});
}
RoleMapping.belongsTo(User);
RoleMapping.belongsTo(Role);
User.hasMany(Role, {through: RoleMapping, foreignKey: 'principalId'});
User.hasMany(RoleMapping, {foreignKey: 'principalId'});
Role.hasMany(User, {through: RoleMapping, foreignKey: 'roleId'});
// Add your custom endpoints
User.customEndpoint1 = function(param1, cb) {...};
User.remoteMethod('customEndpoint1',...){...};
};
样板文件基本上就在那里,因为我们需要手动添加一个 ACL 条目,该条目设置权限以允许任何人请求新的验证电子邮件。如果不这样做,by default the User model denies access by non-authenticated users .
另外,请注意,我们仅在进行初始设置时才在数据库中创建 ACL 条目,即我们只执行一次(除非您设置新数据库)。
但是我们每次启动服务器时都需要配置User、Role和RoleMapping之间的关系,否则会出现合法用户访问错误等奇怪行为。
(注意:虽然这是一项相当多的工作,但我认为能够稍微轻松地向 User 模型添加新功能将允许您将用户管理保留在它所属的位置。)
完成此设置后,您现在可以执行例如
POST https://myserver/api/Users/newVerificationEmail
2. 创建一个端点来请求新的链接
要像使用任何其他模型一样添加端点:
User.newVerificationEmail = function(email, cb) {
console.log("A new verification email was requested for: " + email);
cb(null);
};
User.remoteMethod(
'newVerificationEmail',
{
accepts: [
{arg: 'email', type: 'string'}
],
http: {
verb: 'post'
}
}
);
3.调用verify方法,发送邮件
要发送验证电子邮件,您有几个选项。您可以:
User.verify()
方法 ( located in the user.js model file ) 和默认 SMTP 电子邮件 User.verify()
方法,但使用您自己的 Emailer(例如通过 API 发送)User.verify()
做。但是,这还需要您编写确认逻辑,这还需要更多工作。 User.verify() 与默认电子邮件
要复用verify方法,需要生成verify链接(除了token部分,会由方法自己添加),配置选项,调用方法。
User.newVerificationEmail = function(email, cb) {
console.log("A new verification email was requested");
var userModel = User.constructor;
// Note: To get user.id you need to query the DB
// for the User instance with the requested email
var verifyLink = 'https://' +
hostAddress +
':' +
portNumber +
restApiRoot +
'/Users/confirm' +
'?uid=' +
user.id +
'&redirect=https://' + hostAddress + '/verified?user_id='+user.id;
var options = {
type: 'email',
mailer: Email,
to: user.email,
from: 'sender@example.com',
subject: 'My Email Subject',
template: path.resolve(__dirname, '../views/verify.ejs'),
user: user,
verifyHref: verifyLink,
host: myEmailHost,
port: myEmailPort
};
user.verify(options, function(err, response) {
if (err) {
console.log(err);
}
console.log("Account verification email sent to " + options.to);
cb(null);
});
};
创建电子邮件验证模板
将发送的电子邮件是
options.template
中指定的电子邮件。 ,即 server/views/verify.ejs
该文件应该包含我们再次生成的验证链接。你可以添加任何你想要的 HTML,只要确保添加 verifyHref 变量:
Please click <a href="<%= verifyHref %>">this link</a> to verify your email
完成这些更改后,每当您向
api/Users/newVerificationLink
发出 POST 请求时,它都会发送一封电子邮件。User.verify() 与自定义电子邮件
我还没有完成这个解决方案的实现,但它基本上涉及创建您自己的电子邮件连接器以使用您的提供商的 API(例如 Mandrill、Mailgun 等)和 passing this model in the
options.mailer
field .警告:我尚未测试此代码,并且您需要自己指定几个变量值(例如
hostAddress
、 portNumber
、 restApiRoot
等)。这个答案中的代码是从我正在处理的一个项目的几个部分中提取的,虽然它几乎完成了,但您需要验证没有丢失回调和其他拼写错误和编译器错误,并提供代码来搜索与提供的电子邮件相对应的用户对象(这很容易做到)。
关于javascript - 生成新的验证 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40441368/