node发送手机验证码,koa接入短信demo(云信通),云信通提供免费开发测试账号

提示:node发送手机验证码,koa接入短信demo(云信通)


前言

node发送手机验证码,koa接入短信demo(云信通)

一、云信通配置

1、云信通注册登陆地址:

https://www.yuntongxun.com/user/login

2、账号信息,接入参数ACCOUNT SID、AUTH TOKEN、App ID
在这里插入图片描述
3、短信接入文档

https://doc.yuntongxun.com/pe/5a533de33b8496dd00dce07c

4、配置参数
(1)拼接请求地址
在这里插入图片描述
(2)SigParameter规则
在这里插入图片描述

(3)请求头部以及Authorization规则
在这里插入图片描述
(4)请求数据data,模板短信
在这里插入图片描述

二、使用步骤

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_form"
      >
        <el-form-item v-if="loginType='regist'" label="电话" prop="phone" class="login_list_item">
          <el-input v-model.number="user.phone"></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.code"></el-input>
            <el-button type="primary" @click="getPhoneCode" round>获取验证码</el-button>
          </div>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
import { getPhoneCode } from "@/axios/index";
export default {
  name: "Login",
  data() {
    var validatePhone = (rule, value, callback) => {
      let reg=/^1[34578]\d{9}$/;
      if (value === "") {
        callback(new Error("请输入电话"));
      } else if (!reg.test(this.user.phone)) {
        callback(new Error("请输入正确的电话号码"));
      } else {
        callback();
      }
    };
    var validateCode = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("请输入验证码"));
      } else {
        callback();
      }
    };
    return {
      imgUrl: null,
      msg: "用户注册",
      loginType: "regist",
      user: {
        phone: "",
        code: "",
      },
      rules: {
        phone: [{required: false},{ validator: validatePhone, trigger: "blur" }],
        code: [{required: false},{ validator: validateCode, trigger: "blur" }],
      },
    };
  },
  methods: {
    async getPhoneCode(){
      if(!this.user.phone||this.user.phone==''){
         this.$message({
          type:'error',
          message: "请填写正确电话号码"
        });
        return;
      }
      const obj = await getPhoneCode({phone:this.user.phone});
      console.log(obj,"++++++++++++")
    }
  },
};
</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;
      }
    }
  }
}
</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 getPhoneCode = async (data) => {
  return instance.post('/getPhoneCode', data);
}

export default instance;

3.koa中routes.js

代码如下(示例):

import Router from 'koa-router';
import fs, { readFileSync } from 'fs';
import { phoneCode } from './phoneCode.js'

const router = new Router();

const getPhoneCode = async ctx =>{
    const data = await phoneCode(ctx.request.body.phone);
    console.log(data)
    ctx.body  = {
        code:200,
        data:data,
        msg:'success'
    }
}
router.post('/getPhoneCode ',getPhoneCode );

export default router;

4.koa中phoneCode.js

代码如下(示例):

import md5 from 'md5';
import axios from 'axios';
import { Base64 } from 'js-base64';

const getTimeString = ()=>{
    let date = new Date();
    // date.getMonth()获取当前月份(0-11,0代表1月) 需要+1
    let timeArr = [ date.getFullYear(),date.getMonth()+1,date.getDate(),date.getHours(),date.getMinutes(),date.getSeconds() ]
    let timeString = '';
    timeArr.forEach(num=>{ timeString+=num>9?''+num:'0'+num; });
    return timeString;
   
}

export const phoneCode = async (phone)=> {
    /*
    * 业务URL格式:/2013-12-26/Accounts/{accountSid}/SMS/{funcdes}?sig={SigParameter}
    * 在URL格式中 {}内的内容表示为参数,非{}的内容固定不变。
    */
    let ACCOUNT_SID = '8aaf0708802d0d8501804ac40bef0768';
    let AUTH_TOKEN = '9a383fdf39a84084891443c63393e410';
    let App_ID = '8aaf0708802d0d8501804ac40cec076f';

    /*
    * accountSid	String	必选	开发者主账户ACCOUNT SID(登陆官网在管理控制台获取)
    * SigParameter	String	必选	REST API 验证参数,生成规则如下1.使用MD5加密(账户Id + 账户授权令牌 + 时间戳)。其中账户Id和账户授权令牌根据url的验证级别对应主账户。时间戳是当前系统时间,格式'yyyyMMddHHmmss'。时间戳有效时间为24小时,如:201404161420302.SigParameter参数需要大写,如不能写成sig=abcdefg而应该写成sig=ABCDEFG
    */
   
    let timeString = getTimeString();
    let sig = md5(ACCOUNT_SID+AUTH_TOKEN+timeString).toUpperCase(); //这里不大写也可以
    let url = 'https://app.cloopen.com:8883/2013-12-26/Accounts/'+ACCOUNT_SID+'/SMS/TemplateSMS?sig='+sig;
    
    /*
    * Accept	String	必选	客户端响应接收数据格式:application/xml、application/json
    * Content-Type	String	必选	类型:application/xml;charset=utf-8、application/json;charset=utf-8
    * Content-Length	String	必选	Content-Length
    * Authorization	String	必选	验证信息,生成规则详见下方说明1.使用Base64编码(账户Id + 冒号 + 时间戳)其中账户Id根据url的验证级别对应主账户2.冒号为英文冒号3.时间戳是当前系统时间,格式'yyyyMMddHHmmss',需与SigParameter中时间戳相同。
    */
    let Authorization = Base64.encode(ACCOUNT_SID+':'+timeString);
    let headers = {
        'Accept':'application/json',
        'Content-Type':'application/json;charset=utf-8',
        // 'Content-Length':JSON.stringify(data).length+'',  //这里可以不传,传必须是请求数据stringify的length
        'Authorization':Authorization
    }

    /*
    * to	String	必选	短信接收端手机号码集合,用英文逗号分开,每批发送的手机号数量不得超过200个
    * appId	String	必选	应用Id,官网控制台应用列表获取
    * templateId	String	必选	模板Id,官网控制台模板列表获取。测试模板id是1。测试模板的内容是:【云通讯】您使用的是云通讯短信模板,您的验证码是{1},请于{2}分钟内正确输入
    * datas	Array	可选	内容数据外层数组节点
    * data	String	可选	内容数据,用于替换模板中{序号},模板如果没有变量,此参数可不传,多个变量,使用数组的数据格式
    * subAppend	String	可选	扩展码,四位数字 0~9999
    * reqId	String	可选	第三方自定义消息id,最大支持32位,同账号下同一自然天内不允许重复。
    */

    //生成验证码
    let codeStr = '';
    for(let i=0;i<6;i++){
        codeStr += Math.floor(Math.random()*10);
    }
    let data = {
        to:phone,
        appId:App_ID,
        templateId:'1',
        datas:[codeStr,'1']
    }

    let resData = {codeStr}
   await axios({
        headers,
        method:'POST',
        url,
        data
    }).then(res=>{
        resData.data = res.data
        console.log(res.data,'+++++++++++++')
    }).catch(err=>{
        console.log(err,'err')
    });
    return resData;
}

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,  // 是否允许发送Cookie
    allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],  // 设置所允许的HTTP请求方法
    allowHeaders: ['Content-Type', 'Authorization', 'Accept'],  // 设置服务器支持的所有头信息字段
    exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'] // 设置获取其他自定义字段
}))

const sessionConfig = {
    key: 'koa:sess',   // cookie的key,默认koa:sess
    maxAge: 1000*5,    // 过期时间,毫秒ms
    autoCommit: 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");

总结

踩坑路漫漫长@~@

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值