nuxt全栈仿美团官网05——发送验证码功能

平时在有道云上做笔记,直接发到这里格式全乱了,现在改成Markdown的,效果还凑合,大家也可查看有道云链接: http://note.youdao.com/noteshare?id=3a3ed5e59748451d1e606f384a229e32&sub=F643D721EB1D41D7A6DA8E54CEE6AE48

验证码发送流程:

  1. 启动项目,启动redis,填写用户名和邮箱,点击发送验证码按钮。
  2. 校验用户名,不通过return false。
this.$refs['ruleForm'].validateField('name', (value) => {
  usernamePass = !value
})
if (!usernamePass) { return false }
  1. 校验邮箱。
this.$refs['ruleForm'].validateField('email', (value) => {
  emailPass = !value
})
  1. 如果通过,通过axios发送请求,带参数用户名和邮箱,其中用户名可能有中文,所以要用encodeURIComponent编码(把参数中能编码的全部编了,含http协议中的字符,而encodeURI只把问号后面的参数进行编码)。
this.$axios.post('/users/verify', {
  username: encodeURIComponent(this.ruleForm.name),
  email: this.ruleForm.email
}).then()
  1. 接口收到请求后,取出用户名,先在存于Redis的session中查询验证码过期时间,并与当前时间比较;
    如果还没过期就返回“操作过于频繁”的提示。
    如果不存在或者过期(不存在会转成0比较),进行下一步。
const username = ctx.request.body.username
// session存入Redis
const saveExpire = await Store.hget(`nodemail:${username}`, 'expire')
if (new Date().getTime() < saveExpire) {
  ctx.body = {
    code: -1,
    msg: '请求过于频繁,1分钟内只能发1次'
  }
  return false
}
  1. 用nodeMailer创建一个邮件发送器(这里的源码和视频上不一致,被坑了很久):
let transporter = nodeMailer.createTransport({
  host: Email.smtp.host, // 主机,腾讯的是smtp.qq.com
  post: 587, // 端口
  secure: false,
  auth: {
    user: Email.smtp.user, // 发送服务器的账号
    pass: Email.smtp.pass // 发送服务器的授权码
  }
})
  1. 创建发邮件相关的对象ko和邮件发送选项
const ko = {
  code: Email.smtp.code,
  expire: Email.smtp.expire(),
  user: username,
  email: ctx.request.body.email
}
const options = {
  from: `认证邮件:<${Email.smtp.user}>`,
  to: ko.email,
  subject: '关中刀客在青岛做网站练习的验证码',
  html: '<p>谢谢测试!</p>验证码是:' + Email.smtp.code()
}
  1. 发送邮件,注意前面有await。发送成功后将相关信息写入session存到redis,如果不成功打印错误信息
await transporter.sendMail(options, (error, info) => {
  if (error) { // 发邮件出错,打印并停止
    return console.log(error, info)
  } else {
    // Redis中取session
    Store.hmset(`nodemail:${ko.user}`, 'code', ko.code, 'email', ko.email, 'expire', ko.expire)
  }
})
  1. 设置发送成功标志code
ctx.body = {
  code: 0,
  msg: '验证码发送成功,有效期1分钟。'
}
  1. 在页面的then中,判断页面响应成功并收到成功标志后,设置60秒倒计时的定时器。如果不成功就显示相应信息。
if (status === 200 && data.code === 0) {
  let counter = 60
  const timer = setInterval(() => {
    this.statusMsg = `验证码已发送,请查收! ${--counter}秒后重发`
    if (!counter) { clearInterval(timer)}
  }, 1000)

说明

  • 当验证码还没过期时点击按钮,则服务器返回“操作频繁”的提示,但因页面有定时器,这个提示最多看到1秒钟就会被倒计时替换。
  • 代码仅供参考,可能有很多原因会导致照搬不成功。

其他注意事项

  • 首先揭示一个大坑,坑了我一个多小时:
    源码中的结构不对,不能用,返回错误信息 connect ETIMEDOUT 123.129.254.12:587 at TCPConnectWrap.afterConnect [as oncomplete] ,后来按视频中讲的去配置才可以!
// 错的!
let transporter = nodeMailer.createTransport({
  service: 'qq',
  auth: {
    user: Email.smtp.user,
    pass: Email.smtp.pass
  }
})
// 对的!
let transporter = nodeMailer.createTransport({
  host:Email.smtp.host,
  post:587,
  secure:false,
  auth:{
    user:Email.smtp.user,
    pass: Email.smtp.pass
  }
})
  • elementUI布局中的列宽span前面要加上冒号,否则控制台警告:
Invalid prop: type check failed for prop "span". Expected Number with value 3, got String……
  • server/index.js 中use路由的位置是下面两行代码功能之间,否则连接口都找不到。
if (config.dev) {
  const builder = new Builder(nuxt)
  await builder.build()
} else {
  await nuxt.ready()
}
app.use(users.routes()).use(users.allowedMethods())
app.use((ctx) => {
  ctx.status = 200
  ctx.respond = false // Bypass Koa's built-in response handling
  ctx.req.ctx = ctx // This might be useful later on, e.g. in nuxtServerInit or with nuxt-stash
  nuxt.render(ctx.req, ctx.res)
})
  • 必须引进koa-bodyparser,否则接口从请求头拿不到任何数据。使用位置在start()之前,方法如下:
app.use(bodyparser({
  extendTypes:['json','form','text']
}))

环境版本:

"dependencies": {
  "@nuxtjs/axios": "^5.3.6",
  "cross-env": "^5.2.0",
  "element-ui": "^2.4.11",
  "koa": "^2.6.2",
  "nuxt": "^2.0.0"
},
"devDependencies": {
  "@nuxtjs/eslint-config": "^1.0.1",
  "@nuxtjs/eslint-module": "^1.0.0",
  "babel-cli": "^6.26.0",
  "babel-eslint": "^10.0.1",
  "babel-preset-env": "^1.7.0",
  "eslint": "^6.1.0",
  "eslint-plugin-nuxt": ">=0.4.2",
  "koa-bodyparser": "^4.2.1",
  "koa-passport": "^4.1.3",
  "koa-redis": "^4.0.0",
  "koa-router": "^7.4.0",
  "mongoose": "^5.6.13",
  "node-sass": "^4.12.0",
  "nodemailer": "^6.3.0",
  "nodemon": "^1.18.9",
  "passport-local": "^1.0.0",
  "sass-loader": "^8.0.0"
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值