我做了这个代码,帮助我验证我的电子邮件注册。首先,我在注册时针对每个用户在我的数据库中设置一个秘密令牌。然后我将该秘密令牌发送到带有消息的个人电子邮件,并将此令牌粘贴到用户验证页面进行验证。
这是我的注册API:
router.post('/register', (req, res) => {
const secretToken = randomstring.generate();
var name = req.body.name;
var username = req.body.username;
var email = req.body.email;
var password = req.body.password;
var cpassword = req.body.cpassword;
req.checkBody('name','Name is required').notEmpty();
req.checkBody('email','Email is required').notEmpty();
req.checkBody('email', 'Email is not valid').isEmail();
req.checkBody('username','username is required').notEmpty();
req.checkBody('password','password is required').notEmpty();
req.checkBody('cpassword','passwords do not match').equals(req.body.password);
var errors = req.validationErrors();
if(errors)
{
res.render('register', {
errors: errors
});
}
else
{
User.findOne({email: req.body.email}, function(err, existingUser)
{
if(existingUser)
{
req.flash('error_msg', 'Email address already exits try different one!!');
res.redirect('/users/register');
console.log("In db save body");
}
else
{
var newUser = new User(
{
name:name,
email:email,
username:username,
password:password,
secretToken:secretToken,
active: false
});
User.createUser(newUser, (err,user) => {
if(err) throw err;
console.log(user);
});
//Composing email
const html = `Hi there
<br/>
Thank you for registering!
<br/><br/>
Please verify your email by typing following token:
<br/>
Token : <b>${secretToken}<b>
<br/>
On the following page :
<a href="https://login-app-passport.herokuapp.com/users/verify">https://login-app-passport.herokuapp.com/users/verify</a>
<br/><br/>
Have a good day!`;
mailer.sendEmail('admin@teamfly.com',email,'Please verify your email',html);
req.flash('success_msg','Please check your email');
res.redirect('/users/login');
}
});
}
});
当我将我的秘密令牌放入时,我的数据库更新为secretToken为null,活动状态为false,为真。
这是我的验证API:
router.route('/verify')
.get( (req, res) => {
res.render('verify');
})
.post( (req, res, next) => {
const {secretToken} = req.body;
const user = User.findOne({'secretToken' : secretToken.trim()}).then((user) => {
if(!user)
{
req.flash('error_msg', 'No user found');
res.redirect('/users/verify');
return;
}
user.active = true;
user.secretToken = '';
user.save();
req.flash('success_msg','Thank you.You can now login');
res.redirect('/users/login');
});
});
我的问题是我想发送一个包含秘密令牌的链接,当我点击该链接时,我希望我的数据库自动更新(secretToken为null,活动状态为true)并将我重定向到登录路由。我不想从电子邮件中复制秘密令牌并将其粘贴到验证页面。
答案 0 :(得分:0)
将secretToken
放在验证网址上。用户单击该URL(或将URL复制/粘贴到浏览器中),从URL中提取令牌并更新数据库。
确保secretToken
仅包含网址安全字符,否则您需要对其进行网址编码。
电子邮件:
<a href="https://login-app-passport.herokuapp.com/users/verify/${secretToken}">https://login-app-passport.herokuapp.com/users/verify/${secretToken}</a>
我不知道你正在使用哪个路由器,但是你只需要一个GET / verify /:令牌,不需要POST路由。从.params
提取令牌(如果您愿意,可以提取查询字符串,相应地更新网址)。
router.route('/verify/:secretToken')
.get( (req, res) => {
const {secretToken} = req.params;
const user = User.findOne({'secretToken' : secretToken.trim()}).then((user) => {
if(!user)
{
req.flash('error_msg', 'No user found');
res.redirect('/users/verify-error');
return;
}
user.active = true;
user.secretToken = '';
user.save();
req.flash('success_msg','Thank you.You can now login');
res.redirect('/users/login');
});
答案 1 :(得分:0)
只需使用填充了令牌的网址参数,并在找到用户后进行更新:
您的验证部分:
router.route("/verify/:token").get((res, req) => {
const token = req.params.token;
User.findOneAndUpdate({secretToken: token}, {$set: {secretToken:null, active:true}}, (err, user) => {
if (!err) res.redirect("/users/login")
});
});
您的注册部分:
const verificationLink = `https://login-app-passport.herokuapp.com/verify/${token}`;
const html = `Hi there
<br>
Thank you for registering!
<br><br>
Please verify your email by following this link:
<br>
<b>${verificationLink}<b>
<br>
Have a good day!`;