【Node】Koa调用阿里云短信服务实现用户注册(个人)

目录

一. 购买

1. 在阿里云首页搜索框搜索“短信验证码”

2. 选择其中一个并购买

 二. 代码实现

0. 研究示例代码

1. 发送短信验证码

2. 在数据库中保存短信验证码等信息

3. 校验输入的注册信息

4. 注册


一. 购买

没有企业资质,个人想要调用阿里云短信服务,我的解决办法是购买其他公司已经开通的阿里云短信服务。

1. 在阿里云首页搜索框搜索“短信验证码”

2. 选择其中一个并购买

我选择的是这个,有提供免费次数,价格相对比较实惠

链接:【体验价2分5】三网短信接口-短信验证码-通知短信-短信验证码接口-三网短信接口-短信通知-短信验证码-验证码短信-服务短信【最新版】_商业智能_电商_金融-云市场-阿里云

 购买成功后可以在 已购买的服务【阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台】 中看到短信验证码的AppKey、AppSecret、AppCode这些信息

 二. 代码实现

0. 研究示例代码

购买页下面有请求示例,但是并没有Nodejs的示例,这就让我头疼了很久(框起来的信息都非常重要,要看仔细了);

后来我在这个链接中【阿里云 OpenAPI 开发者门户】找到了Node.js版本的调用示例。

1. 发送短信验证码

async sendMessage(ctx, next) {
  const customerPhoneNumber = ctx.request.query.customerPhoneNumber;

  const AppCode = "<your-AppCode>"
  const AppKey = "<your-AppKey>"
  const AppSecret = "<your-AppSecret>"
  const Host = "https://dfsns.market.alicloudapi.com" // 购买页示例中的主机地址
  const Path = "/data/send_sms" // 购买页示例中的路径
  const templateId = "TPL_0000" // 购买页示例中的模板编号

  const client = new Core({
    accessKeyId: AppKey,
    accessKeySecret: AppSecret,
    endpoint: Host + Path,
    apiVersion: '2017-05-25'
  });

  // 生成n位随机0~9的验证码
  const geneRandomCode = (n) => {
    let code = ""
    for (let i = 0; i < n; i++) {
      code += parseInt(Math.random() * 10)
    }
    return code
  }
  const code = geneRandomCode(6)

  const params = {
    content: `code:${code}`,
    ["phone_number"]: customerPhoneNumber,
    ["template_id"]: templateId
  }

  const requestOption = {
    method: 'POST',
    formatParams: false,
    headers: {
      Authorization: `APPCODE ${AppCode}`,
      ["Content-Type"]: "application/x-www-form-urlencoded; charset=UTF-8"
    }
  }

  try {
    const response = await client.request('SendSms', params, requestOption)
    // console.log('response', response)
    if (response.status === 'OK') {
      const message = {
        customerPhoneNumber,
        code,
        expirationTime: new Date().getTime() + EXPIRATION_TIME + ""
      }
      console.log(message);
      // 在数据库中保存用户手机号+短信验证码+过期时间戳
      await userService.saveSMSCode(message)
      ctx.body = {
        code: '200',
        message: '发送成功'
      }
    } else {
      ctx.body = {
        code: '400',
        message: '发送失败'
      }
    }
  } catch (error) {
    console.log('error', error)
  }
}

expirationTime过期时间我是通过getTime的方法获取当前的13位时间戳(单位毫秒ms),再加上一个常量

const EXPIRATION_TIME = 1000 * 60 * 5 // 5分钟

2. 在数据库中保存短信验证码等信息

讲道理在Redis中保存短信验证码设置过期时间会更加规范,简单起见我就保存在MySQL里了。

async saveSMSCode(message) {
  const {
    customerPhoneNumber,
    code,
    expirationTime
  } = message
  let statement = `SELECT * FROM smscode WHERE customerPhoneNumber = ?`
  let result = await connection.execute(statement, [customerPhoneNumber])
  // 如果查不到就插入新的数据 查到了就更新替换短信验证码 + 过期时间
  if (result[0].length === 0) {
    statement = `INSERT INTO smscode (customerPhoneNumber, code, ExpirationTime) VALUES(?, ?, ?)`
    result = await connection.execute(statement, [customerPhoneNumber, code, expirationTime])
  } else {
    statement = `UPDATE smscode SET code = ? , ExpirationTime = ? WHERE customerPhoneNumber = ?`
    result = await connection.execute(statement, [code, expirationTime, customerPhoneNumber])
  }
}

3. 校验输入的注册信息

编写中间件verifyRegisterInfo对用户输入的注册信息进行校验;

主要从三个方面进行校验:

  1. 判断用户输入的信息是否合法,例如手机号长度等
  2. 在数据库中查询用户输入的手机号是否被注册过
  3. 查看验证码是否正确并未过期
const verifyRegisterInfo = async (ctx, next) => {
  const {
    customerPhoneNumber,
    code
  } = ctx.request.body
  try {
    // 1. 判断用户填入信息是否合法
    // 前端已经判断

    // 2. 查询手机号是否被注册过
    let result = await userService.getPhone(customerPhoneNumber)
    // console.log("查询手机号是否被注册过:", result);
    if (result.length !== 0) {
      const error = new Error(errorType.PHONE_ALREADY_EXISTS)
      return ctx.app.emit("error", error, ctx)
    }

    // 3. 查看验证码是否正确或过期
    const message = {
      customerPhoneNumber,
      code,
      curTime: new Date().getTime()
    }
    result = await userService.checkCode(message)
    // console.log("查看验证码是否正确或过期:", result);
    if (result.length === 0) {
      const error = new Error(errorType.CODE_IS_EXPIRED_OR_INCORRECT)
      return ctx.app.emit("error", error, ctx)
    }

    await next()
  } catch (err) {
    console.log(err);
  }
}

若用户传入的注册信息不合法,则会抛出错误,若没有错误则会执行next(),交给下一个中间件register处理

async getPhone(customerPhoneNumber) {
  let statement = `SELECT * FROM customer WHERE customer_phone_number = ?`
  let result = await connection.execute(statement, [customerPhoneNumber])

  return result[0]
}

async checkCode(message) {
  const {
    customerPhoneNumber,
    code,
    curTime
  } = message
  const statement = `SELECT * FROM smscode WHERE customerPhoneNumber = ? AND code = ? AND expirationTime >= ?`
  const result = await connection.execute(statement, [customerPhoneNumber, code, curTime])

  return result[0]
}

4. 注册

编写中间件register;

在数据库中插入用户注册的数据;

async register(ctx, next) {
  const {
    customerPhoneNumber,
    customerPassword
  } = ctx.request.body
  const message = {
    customerPhoneNumber,
    customerPassword
  }
  await userService.register(message)
  ctx.body = {
    status: 200,
    message: "注册成功~"
  }
}
async register(message) {
  const {
    customerPhoneNumber,
    customerPassword
  } = message
  let statement = `INSERT INTO customer (customer_phone_number, customer_password) VALUES(?, ?)`
  const result = await connection.execute(statement, [customerPhoneNumber, customerPassword])

  return result[0]
}

以上步骤便完整了通过Koa调用阿里云短信服务实现用户注册的功能。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值