提示:koa发送验证码至邮箱,QQ邮箱发送
文章目录
- 前言
- 一、依赖和邮箱设置
- 二、使用步骤
- 1.vue中Login.vue
- 2.vue中axios.js
- 3.koa中routes.js
- 4.koa中emailCode.js
- 5.koa中app.js
- 总结
前言
koa发送验证码至邮箱,QQ邮箱发送
一、依赖和邮箱设置
npm install nodemailer --save
二、使用步骤
1.vue中Login.vue
代码如下(示例):
<template><div class="login_box"><div class="login_list"><el-form:model="user"status-icon:rules="rules"ref="loginForm"label-width="80px"class="login_orm"><el-form-item label="邮箱" v-if="loginType='regist'" prop="email" class="login_list_item"><el-inputv-model="user.email"autocomplete="off"></el-input></el-form-item><el-form-item v-if="loginType='regist'" label="邮箱验证码" prop="code" class="login_list_item"><div class="login_item"><el-input v-model.number="user.emailCode"></el-input><el-button type="primary" :disabled="disabledEmailCode" @click="getEmailCode" round>{{!disabledEmailCode?'获取验证码':countNum+'s'}}</el-button></div></el-form-item></el-form></div></div>
</template><script>
import { regist,getPhoneCode, getImgCode, getEmailCode } from "@/axios/index";export default {name: "Login",data() {var validateEmail = (rule, value, callback) => {if (value === "") {callback(new Error("请输入邮箱"));} else {if(value != ""){if(!this.emailReg.test(value)){callback(new Error("请输入正确的邮箱"));return}}callback();}};var validateEmailCode = (rule, value, callback) => {if (value === "") {callback(new Error("请输入验证码"));} else {callback();}};return {imgUrl: null,msg: "用户注册",loginType: "regist",imgCodeUrl:null,disabledPhoneCode:false,disabledEmailCode:false,countNum:60,countTimer:null,emailReg:/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/,user: {email: "",emailCode:"",},rules: {email: [{required: false},{ validator: validateEmail, trigger: "blur" }],emailCode: [{required: false},{ validator: validateEmailCode, trigger: "blur" }],},};},created(){},methods: {getEmailCode(){if(!this.emailReg.test(this.user.email)&&this.user.email!=''){this.$message.error();('请输入正确的邮箱');return}getEmailCode({email:this.user.email}).then(()=>{this.$message.success();('验证码已发送邮箱');})},},
};
</script>
<style scoped lang="scss">
.login_box {position: relative;height: 100%;.login_list {width: 400px;position: absolute;box-sizing: border-box;top: 50%;left: 50%;transform: translate(-50%, -50%);.login_title {font-size: 16px;text-align: center;}.login_item{display: flex;.el-button.is-round{padding: 0 14px;margin-left: 30px;height: 26px;position: relative;top: 8px;}.login_item_img{height: 40px;width: 160px;margin-left: 30px;}}}
}
</style>
<style>.login_box .login_list .el-form-item__label{text-align: justify;height: 40px;overflow: hidden;
}
.login_box .login_list .el-form-item__label::after{content: "";display: inline-block;width: 100%;height: 100%;
}
</style>
2.vue中axios.js
代码如下(示例):
import axios from 'axios';
import { Loading, Message } from 'element-ui';let urlData = { basicUrl: "http://127.0.0.1:3002" }let loading;const instance = axios.create({baseURL: urlData.basicUrl,timeout: 1000,headers: { "X-Requested-With": "XMLHttpRequest" },withCredentials: false,
});// 添加请求拦截器
instance.interceptors.request.use(function (config) {// 在发送请求之前做些什么loading = Loading.service({lock: true, // 是否锁屏text: '正在加载...', // 加载动画的文字spinner: 'el-icon-loading', // 引入的loading图标background: 'rgba(0, 0, 0, 0.3)', // 背景颜色})return config;
}, function (error) {// 对请求错误做些什么return Promise.reject(error);
});// 添加响应拦截器
instance.interceptors.response.use(function (response) {loading.close();// 对响应数据做点什么return response.data;
}, function (error) {// 对响应错误做点什么return Promise.reject(error);
});export const getImgCode = async () => {return instance.get('/getImgCode');
}export default instance;
3.koa中routes.js
代码如下(示例):
import Router from 'koa-router';
import fs, { readFileSync } from 'fs';
import { sendEmail } from './emaiCode.js'const router = new Router();const getEmailCode = async ctx => {let codeStr = ""; //验证码let codeLen = 6; //验证码长度for(let i=0;i<codeLen;i++){codeStr += Math.floor(Math.random()*10);}var mail = {from: `""<xxx@xx.xxx>`, //发件邮箱subject: "验证码",to: ctx.request.body.email, //收件邮箱text: "验证码为:" + codeStr, //发送内容};const res = await sendEmail(mail);ctx.session.emailCode = codeStr;ctx.session.emailCodeTime = new Date().getTime();ctx.body = {code: 200,data: res.info,msg: 'success'}}
router.post('/getEmailCode ',getEmailCode );export default router;
4.koa中emailCode.js
代码如下(示例):
import Nodemailer from 'nodemailer'
const config = {host: "smtp.qq.com",port: 465,secureConnection: true,service: "qq",auth: {user: "xxx@xxx.xxx", //发件账号pass: "xxxxxxxxxx", //发件邮箱授权码},
};
const transport = Nodemailer.createTransport(config);export const sendEmail = async (mail) => {let res = {};let start_time = new Date().getTime();return new Promise((resolve,reject)=>{transport.sendMail(mail, (err, info) => {res.err = err;res.info = info;console.log(new Date().getTime() - start_time,"ms")resolve(res);});})
}
5.koa中app.js
代码如下(示例):
import koa from 'koa';
import cors from 'koa-cors';
import router from './routes/routes.js';
import staticFiles from 'koa-static';
import koaBody from 'koa-body';
import session from 'koa-session'import path from 'path';const __dirname = path.resolve();
const app = new koa();app.use(cors({ // 指定一个或多个可以跨域的域名origin: function (ctx) { // 设置允许来自指定域名请求if (ctx.url === '/') {return "*"; // 允许来自所有域名请求, 这个不管用}// return 'http://localhost:8000'; // 这样就能只允许 http://localhost:8000 这个域名的请求了return '*'; // 这样就能只允许 http://localhost:8000 这个域名的请求了},maxAge: 5, // 指定本次预检请求的有效期,单位为秒。credentials: true, // 是否允许发送CookieallowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], // 设置所允许的HTTP请求方法allowHeaders: ['Content-Type', 'Authorization', 'Accept'], // 设置服务器支持的所有头信息字段exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'] // 设置获取其他自定义字段
}))const sessionConfig = {key: 'koa:sess', // cookie的key,默认koa:sessmaxAge: 1000*5, // 过期时间,毫秒msautoCommit: true, // 提交到响应头overwrite: true, // 重写httpOnly: true, // 无法获得Cookie信息signed: true, // 签名rolling: true, // 每次刷新renew: false, // 快过期刷新
};
app.keys = ["long long age"]; // signed签名key
app.use(session(sessionConfig, app)); //第二个参数是app ----------------//解析formdata过来的数据
app.use(koaBody({ multipart: true,formidable: {//上传文件存储目录uploadDir: path.join(__dirname, `/public/uploads/`),//允许保留后缀名keepExtensions: true,multipart: true,},jsonLimit:'10mb',formLimit:'10mb',textLimit:'10mb'
}));
app.use(router.routes());
app.use(router.allowedMethods());
app.use(staticFiles(__dirname + '/public'));
app.listen('3002');
console.log("项目启动,访问:","localhost:3002");
总结
踩坑路漫漫长@~@