📅  最后修改于: 2023-12-03 15:37:24.931000             🧑  作者: Mango
如果你的应用程序需要进行电子邮件验证,你可能会考虑使用 OTP(一次性密码)来保证安全性。本文将介绍如何在 NodeJS 中使用 OTP 进行电子邮件验证。
OTP 是一种用于验证身份的方法,它基于时间或者计数器生成密码。使用 OTP,每个用户都可以拥有一个唯一的密码,这个密码只能用一次。
在 OTP 的基础上,也可以继续进行加密增强以提高安全性,例如使用 TOTP(基于时间的 OTP)或 HOTP(基于计数器的 OTP)。
我们可以使用 speakeasy
包轻松地在 NodeJS 中使用 TOTP 进行电子邮件验证。以下是典型的工作流程:
以下是如何在 NodeJS 中实现这个工作流程的示例代码:
const express = require('express');
const speakeasy = require('speakeasy');
const QRCode = require('qrcode');
const nodemailer = require('nodemailer');
const app = express();
// Generate TOTP secret key
app.get('/api/generate-secret', (req, res) => {
const secret = speakeasy.generateSecret({length: 20});
res.send(secret);
});
// Generate TOTP QR code
app.get('/api/generate-qr-code', (req, res) => {
const otpauthUrl = speakeasy.otpauthURL({
secret: req.query.secret.base32,
label: 'My App',
algorithm: 'sha1',
encoding: 'base32'
});
QRCode.toDataURL(otpauthUrl)
.then(dataUrl => {
res.send(dataUrl);
});
});
// Send TOTP key via email
app.post('/api/send-email', (req, res) => {
const email = req.body.email;
const secret = req.body.secret.base32;
const transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: process.env.GMAIL_ACCOUNT,
pass: process.env.GMAIL_PASSWORD
}
});
const otpauthUrl = speakeasy.otpauthURL({
secret: secret,
label: 'My App',
algorithm: 'sha1',
encoding: 'base32'
});
const mailOptions = {
from: process.env.GMAIL_ACCOUNT,
to: email,
subject: 'Verification code for My App',
text: `Please enter the following code to verify your email address: ${speakeasy.totp({secret: secret, encoding: 'base32'})}`,
html: `<p>Please enter the following code to verify your email address:</p><p style="font-size: 2em;font-weight: bold;">${speakeasy.totp({secret: secret, encoding: 'base32'})}</p><br/><img src="${otpauthUrl}"/>`
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.error('Error occurred:', error.message);
res.sendStatus(400);
} else {
console.log('Message sent');
res.sendStatus(200);
}
});
});
// Verify TOTP code
app.post('/api/verify', (req, res) => {
const secret = req.body.secret.base32;
const code = req.body.code;
const verified = speakeasy.totp.verify({
secret: secret,
encoding: 'base32',
token: code
});
if (verified) {
res.sendStatus(200);
} else {
res.sendStatus(400);
}
});
app.listen(3000, () => {
console.log('Server started on port 3000');
});
在上述示例代码中,我们生成 TOTP 密钥、生成 TOTP QR 码、通过电子邮件发送 TOTP 密钥以及验证 TOTP 代码。请注意,实际应用程序需要更多的错误处理和安全性功能。