我正在尝试为用户构建确认电子邮件地址,以验证他们的电子邮件是否真实。我应该用什么软件包来确认用户的电子邮件地址。到目前为止我使用mongoose并表达
代码示例
var UserSchema = new mongoose.Schema({
email: { type: String, unique: true, lowercase: true }
password: String
});
var User = mongoose.model('User', UserSchema);
app.post('/signup', function(req, res, next) {
// Create a new User
var user = new User();
user.email = req.body.email;
user.password = req.body.password;
user.save();
});
在app.post代码中,如何确认用户的电子邮件地址?
答案 0 :(得分:109)
您要查找的内容称为“帐户验证”或“电子邮件验证”。有很多Node模块可以执行此操作,但原理如下:
active
的{{1}}属性false
active
} false
属性设置为active
您的用户现已经过验证。
答案 1 :(得分:20)
var express=require('express');
var nodemailer = require("nodemailer");
var app=express();
/*
Here we are configuring our SMTP Server details.
STMP is mail server which is responsible for sending and recieving email.
*/
var smtpTransport = nodemailer.createTransport("SMTP",{
service: "Gmail",
auth: {
user: "Your Gmail ID",
pass: "Gmail Password"
}
});
var rand,mailOptions,host,link;
/*------------------SMTP Over-----------------------------*/
/*------------------Routing Started ------------------------*/
app.get('/',function(req,res){
res.sendfile('index.html');
});
app.get('/send',function(req,res){
rand=Math.floor((Math.random() * 100) + 54);
host=req.get('host');
link="http://"+req.get('host')+"/verify?id="+rand;
mailOptions={
to : req.query.to,
subject : "Please confirm your Email account",
html : "Hello,<br> Please Click on the link to verify your email.<br><a href="+link+">Click here to verify</a>"
}
console.log(mailOptions);
smtpTransport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
res.end("error");
}else{
console.log("Message sent: " + response.message);
res.end("sent");
}
});
});
app.get('/verify',function(req,res){
console.log(req.protocol+":/"+req.get('host'));
if((req.protocol+"://"+req.get('host'))==("http://"+host))
{
console.log("Domain is matched. Information is from Authentic email");
if(req.query.id==rand)
{
console.log("email is verified");
res.end("<h1>Email "+mailOptions.to+" is been Successfully verified");
}
else
{
console.log("email is not verified");
res.end("<h1>Bad Request</h1>");
}
}
else
{
res.end("<h1>Request is from unknown source");
}
});
/*--------------------Routing Over----------------------------*/
app.listen(3000,function(){
console.log("Express Started on Port 3000");
});
按照代码示例,您可以使用nodemailer
发送链接,然后验证它。
这是一个链接:https://codeforgeek.com/2014/07/node-email-verification-script/
答案 2 :(得分:8)
我想提出一种与提议的方法略有不同的方法。
此方法不会将哈希放入数据库(因此与哈希的交互较少)
您不需要在数据库中注册哈希。收到注册请求后的概述如下:
翻译成代码,您将得到以下内容:
1-编码令牌
function encodeRegistrationToken()
{
// jsonweb automatically adds a key that determines the time, but you can use any module
const jwt = require('jsonwebtoken');
// The information we need to find our user in the database (not sensible info)
let info = {id: yourUserId};
// The hash we will be sending to the user
const token = jwt.sign(info, "yoursecretkey");
return token;
}
// ...
let token = encodeRegistrationToken();
2-通过任何适当的方式将令牌发送给用户
// Your implementation of sending the token
sendTokenToUser(token);
3-解码令牌
function decodeRegistrationToken(token)
{
const jwt = require('jsonwebtoken');
let decoded = jwt.verify(token, "yoursecretkey");
let userId = decoded.id;
// Check that the user didn't take too long
let dateNow = new Date();
let tokenTime = decoded.iat * 1000;
// Two hours
let hours = 2;
let tokenLife = hours * 60 * 1000;
// User took too long to enter the code
if (tokenTime + tokenLife < dateNow.getTime())
{
return {
expired: true
};
}
// User registered in time
return {
userID
};
}
4-更新数据库
或
快速说明:如果需要,您可以在对令牌进行编码时进一步对用户ID进行编码(易于访问)。
答案 3 :(得分:6)
步骤1:
用户模型
var userSchema = new mongoose.Schema({
email: { type: String, unique: true },
isVerified: { type: Boolean, default: false },
password: String,
});
令牌模型
const tokenSchema = new mongoose.Schema({
_userId: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'User' },
token: { type: String, required: true },
expireAt: { type: Date, default: Date.now, index: { expires: 86400000 } }
});
第2步:登录
exports.login = function(req, res, next) {
User.findOne({ email: req.body.email }, function(err, user) {
// error occur
if(err){
return res.status(500).send({msg: err.message});
}
// user is not found in database i.e. user is not registered yet.
else if (!user){
return res.status(401).send({ msg:'The email address ' + req.body.email + ' is not associated with any account. please check and try again!'});
}
// comapre user's password if user is find in above step
else if(!Bcrypt.compareSync(req.body.password, user.password)){
return res.status(401).send({msg:'Wrong Password!'});
}
// check user is verified or not
else if (!user.isVerified){
return res.status(401).send({msg:'Your Email has not been verified. Please click on resend'});
}
// user successfully logged in
else{
return res.status(200).send('User successfully logged in.');
}
});
});
第3步:注册
exports.signup = function(req, res, next) {
User.findOne({ email: req.body.email }, function (err, user) {
// error occur
if(err){
return res.status(500).send({msg: err.message});
}
// if email is exist into database i.e. email is associated with another user.
else if (user) {
return res.status(400).send({msg:'This email address is already associated with another account.'});
}
// if user is not exist into database then save the user into database for register account
else{
// password hashing for save into databse
req.body.password = Bcrypt.hashSync(req.body.password, 10);
// create and save user
user = new User({ name: req.body.name, email: req.body.email, password: req.body.password });
user.save(function (err) {
if (err) {
return res.status(500).send({msg:err.message});
}
// generate token and save
var token = new Token({ _userId: user._id, token: crypto.randomBytes(16).toString('hex') });
token.save(function (err) {
if(err){
return res.status(500).send({msg:err.message});
}
// Send email (use credintials of SendGrid)
var transporter = nodemailer.createTransport({ service: 'Sendgrid', auth: { user: process.env.SENDGRID_USERNAME, pass: process.env.SENDGRID_PASSWORD } });
var mailOptions = { from: 'no-reply@example.com', to: user.email, subject: 'Account Verification Link', text: 'Hello '+ req.body.name +',\n\n' + 'Please verify your account by clicking the link: \nhttp:\/\/' + req.headers.host + '\/confirmation\/' + user.email + '\/' + token.token + '\n\nThank You!\n' };
transporter.sendMail(mailOptions, function (err) {
if (err) {
return res.status(500).send({msg:'Technical Issue!, Please click on resend for verify your Email.'});
}
return res.status(200).send('A verification email has been sent to ' + user.email + '. It will be expire after one day. If you not get verification Email click on resend token.');
});
});
});
}
});
});
第4步:验证帐户
// It is GET method, you have to write like that
// app.get('/confirmation/:email/:token',confirmEmail)
exports.confirmEmail = function (req, res, next) {
Token.findOne({ token: req.params.token }, function (err, token) {
// token is not found into database i.e. token may have expired
if (!token){
return res.status(400).send({msg:'Your verification link may have expired. Please click on resend for verify your Email.'});
}
// if token is found then check valid user
else{
User.findOne({ _id: token._userId, email: req.params.email }, function (err, user) {
// not valid user
if (!user){
return res.status(401).send({msg:'We were unable to find a user for this verification. Please SignUp!'});
}
// user is already verified
else if (user.isVerified){
return res.status(200).send('User has been already verified. Please Login');
}
// verify user
else{
// change isVerified to true
user.isVerified = true;
user.save(function (err) {
// error occur
if(err){
return res.status(500).send({msg: err.message});
}
// account successfully verified
else{
return res.status(200).send('Your account has been successfully verified');
}
});
}
});
}
});
});
第5步:重新发送链接
exports.resendLink = function (req, res, next) {
User.findOne({ email: req.body.email }, function (err, user) {
// user is not found into database
if (!user){
return res.status(400).send({msg:'We were unable to find a user with that email. Make sure your Email is correct!'});
}
// user has been already verified
else if (user.isVerified){
return res.status(200).send('This account has been already verified. Please log in.');
}
// send verification link
else{
// generate token and save
var token = new Token({ _userId: user._id, token: crypto.randomBytes(16).toString('hex') });
token.save(function (err) {
if (err) {
return res.status(500).send({msg:err.message});
}
// Send email (use credintials of SendGrid)
var transporter = nodemailer.createTransport({ service: 'Sendgrid', auth: { user: process.env.SENDGRID_USERNAME, pass: process.env.SENDGRID_PASSWORD } });
var mailOptions = { from: 'no-reply@example.com', to: user.email, subject: 'Account Verification Link', text: 'Hello '+ user.name +',\n\n' + 'Please verify your account by clicking the link: \nhttp:\/\/' + req.headers.host + '\/confirmation\/' + user.email + '\/' + token.token + '\n\nThank You!\n' };
transporter.sendMail(mailOptions, function (err) {
if (err) {
return res.status(500).send({msg:'Technical Issue!, Please click on resend for verify your Email.'});
}
return res.status(200).send('A verification email has been sent to ' + user.email + '. It will be expire after one day. If you not get verification Email click on resend token.');
});
});
}
});
});
您可以从以下链接获取帮助:https://medium.com/@slgupta022/email-verification-using-sendgrid-in-node-js-express-js-mongodb-c5803f643e09
答案 4 :(得分:5)
我花了很多时间弄清楚发送确认邮件的完美方式。这是我使用的方法。
图书馆
const jwt = require('jsonwebtoken');
const nodemailer = require("nodemailer");
第1步 将用户ID编码为带有到期日期的jwt令牌
var date = new Date();
var mail = {
"id": user.id,
"created": date.toString()
}
const token_mail_verification = jwt.sign(mail, config.jwt_secret_mail, { expiresIn: '1d' });
var url = config.baseUrl + "verify?id=" + token_mail_verification;
第2步 使用nodemailer库将令牌发送到用户电子邮件地址
let transporter = nodemailer.createTransport({
name: "www.domain.com",
host: "smtp.domain.com",
port: 323,
secure: false, // use SSL
auth: {
user: "user@domain.com", // username for your mail server
pass: "Password", // password
},
});
// send mail with defined transport object
let info = await transporter.sendMail({
from: '"NAME" <user@domain.com>', // sender address
to: user.email, // list of receivers seperated by comma
subject: "Account Verification", // Subject line
text: "Click on the link below to veriy your account " + url, // plain text body
}, (error, info) => {
if (error) {
console.log(error)
return;
}
console.log('Message sent successfully!');
console.log(info);
transporter.close();
});
第3步 接受验证链接
app.get('/verify', function(req, res) {
token = req.query.id;
if (token) {
try {
jwt.verify(token, config.jwt_secret_mail, (e, decoded) => {
if (e) {
console.log(e)
return res.sendStatus(403)
} else {
id = decoded.id;
//Update your database here with whatever the verification flag you are using
}
});
} catch (err) {
console.log(err)
return res.sendStatus(403)
}
} else {
return res.sendStatus(403)
}
})
第4步 喝杯咖啡,谢谢,可以节省很多时间
PS:此nodemailer SMTP方法甚至可以与您的主机一起使用。因此,无需去寻求第三方。您还可以找到将gmail与nodemailer结合使用的方法。
答案 5 :(得分:4)
如果您只是在本地计算机上进行测试,了解如何操作的一种简单方法可以是:
假设您已经知道通过nodemailer发送邮件..
用户注册后,在您的数据库中存储注册数据后,在您的服务器端从收到的注册数据和随机生成的数字中获取用户电子邮件,并构建一个自定义网址,其中包含用户所在页面的地址在他/她点击邮件中给出的链接后执导。
var customUrl = "http://"+ your host + "/" + your verification web-page + "?email=" + userEmail + "&id=" + randomNumber;
一个例子可以是:
var userEmail = someone@example.com
var host = localhost:8080
var directWebPage = verifyUserEmail.html
var randomNumber = // generate with math.random() // lets say 111
使用上面的customUrl格式,它看起来像这样
customUrl:http://localhost:8080/verifyUserEmail.htmlemail=someone@example.com&id=111
将此customUrl保存在某处(可能在您的数据库中) 现在,使用包含此cutomUrl链接的电子邮件正文向用户发送电子邮件。
<a href="customUrl">Click to verify your email</a>
当用户点击链接时,他/她将被定向到 verifyUserEmail.html 页面,当发生这种情况时,您可以提取页面 网址 包含 电子邮件 和 id 信息
例如,在角度我就像这样 -
var urlVerifyData = $location.url(); or $location.absUrl();
现在使用javascript字符串方法从 电子邮件 表单 urlVerifyData 字符串
使用此 电子邮件 和 urlVerifyData
请求您的服务器现在向您的数据库查询此电子邮件,并使用用户的 urlVerifyData
验证以前存储的 customUrl如果匹配,hola!你有一个真正的用户!!!
答案 6 :(得分:0)
请使用NPM软件包(两步身份验证)
我制作了一个NPM软件包,可以用来验证您提供的电子邮件ID,该软件包将接收电子邮件ID并返回给您一个OTP,然后发送与您提供相同OTP的电子邮件ID,您可以进行验证然后将散列的邮件ID轻松存储在您的数据库中,并确保它们是真实的:)
Kindly check the full procedures with example here
const {Auth} = require('two-step-auth');
async function login(emailId){
const res = await Auth(emailId);
// You can follw the above approach, But we recommend you to follow the one below, as the mails will be treated as important
const res = await Auth(emailId, "Company Name");
console.log(res);
console.log(res.mail);
console.log(res.OTP);
console.log(res.success);
}
login("YourEmail@anyDomain.com")
答案 7 :(得分:-2)
function generateLink() {
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var token = '';
for (var i = 16; i > 0; --i) {
var rand = Math.round(Math.random() * (chars.length - 1))
token += chars[rand];
}
var link = "http://localhost" + "/verify?id=" + token;
return link;
}
// npm install @sendGrid/mail --save
//library for generating link using SendGrid
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey("SENDGRID_API_KEY"); //create an account on sendgrid and get an API key
// generated link is send to the user's email for email verification
let sendVerifyEmailLink = (req, res) => {
var link = generateLink();
const msg = {
to: 'test@gmail.com',
from: 'test@gmail.com',
subject: 'Account Verifictaion',
text: 'Hello,\n\n' + 'Please verify your account by clicking the link:\/\/\n',
html: 'Hello,\n\n <br> Please verify your account by clicking the link: \n <br> <strong><a href = ' + link + '>http:\/\/ Click here to verify the given Link </a></strong>.\n .<br>Thanks<br>',
};
sgMail.send(msg).then(() => { }, error => {
console.error(error);
if (error.response) {
console.error(error.response.body)
}
});
console.log(msg)
}