邮箱发送验证码(nodemailer)
邮箱发送验证码
- 打开`SMTP` 服务
- 使用 Node.js 邮件发送模块(nodemailer)
- 封装验证码组件
开发中经常会遇到需要验证码,不过手机验证码需要money,不到必要就不必花费,所以可以使用邮箱发送验证码
打开SMTP
服务
根据自己想使用的邮箱,在官网找到并打开smtp服务
不同邮箱服务商的 SMTP 服务器配置有所不同,如 QQ 邮箱的 SMTP 服务器是
smtp.qq.com
,端口一般是 465(SSL)或 587(TLS)
使用 Node.js 邮件发送模块(nodemailer)
npm install nodemailer
配置nodemailer
配置项
'use strict';
const nodemailer = require('nodemailer');
exports.main = async (event, context) => {
const { mail } = event;
// 创建6位随机验证码
const code = Math.floor(Math.random() * 900000) + 100000;
// 创建一个 SMTP 服务器配置对象
let transporter = nodemailer.createTransport({
service: 'QQ', // 使用 QQ 邮箱服务
auth: {
user: '', // 发送方邮箱
pass: '' // 发送方邮箱授权码,需要替换为实际的授权码
}
});
// 邮件内容
let mailOptions = {
from: '', // 发送方邮箱
to: mail, // 接收方邮箱
subject: '验证码', // 邮件主题
text: '您的验证码是:' + code, // 邮件正文(纯文本)
// html: '<b>您的验证码是:' + code + '</b>' // 邮件正文(HTML 格式)
};
try {
// 发送邮件
const info = await transporter.sendMail(mailOptions);
console.log('Message sent: %s', info.messageId);
// 预览邮件链接
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
// 返回数据给客户端
return {
code: 0,
data: {
mail,
code
},
msg: '发送成功'
};
} catch (error) {
console.error(error);
return {
code: 1,
msg: '发送失败'
};
}
};
注意:nodemailer是在node环境中使用的,所以要在云函数中使用
封装验证码组件
一般情况下,登陆、注册、忘记密码等功能都会需要使用到验证码功能,所以将获取验证码封装为一个组件可以提高复用率
尽量将相关的计算操作都涵盖到组件,比如验证码有效期定时器、邮箱验证、云函数调用等
<template>
<view class="code-container">
<button @click="getCode">{{ getFlag?`还剩${countdown}秒`:`获取验证码` }}</button>
</view>
</template>
<script setup>
import {
defineProps,
defineEmits,
ref,
onBeforeUnmount
} from 'vue';
const props = defineProps({
email: {
type: String,
default: ''
}
});
const emits = defineEmits(['transmitcode']);
// 是否获取验证码的标志位
const getFlag = ref(false);
// 定时器
const timer = ref(null);
// 倒计时,验证码有效期
const countdown = ref(60);
const getCode = () => {
if (getFlag.value) return;
// 判断邮箱是否为空
if (!props.email) return;
// 验证邮箱格式
const reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
if (!reg.test(props.email)) {
uni.showToast({
title: '请输入正确的邮箱格式',
icon: 'none'
});
return;
};
// 发送验证码
uniCloud.callFunction({
name: 'getCode',
data: { mail: props.email },
success: res => {
uni.showToast({
title: '验证码已发送',
icon: 'success'
});
// 将获得的验证码交给父组件进行判断
emits('transmitcode', res.result.data.code);
getFlag.value = true;
timer.value = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
clearInterval(timer.value);
getFlag.value = false;
countdown.value = 60;
}
}, 1000);
},
fail: err => {
uni.showToast({
title: '验证码发送失败',
icon: 'none'
});
}
});
};
// 组件销毁时清除定时器
onBeforeUnmount(() => {
clearInterval(timer.value);
});
</script>