微信小程序中短信验证码登录全流程及代码

本文详细介绍了一种基于微信小程序的短信验证码登录实现方案,利用榛子云短信平台完成短信发送,结合Spring MVC进行后端处理。文章深入解析了从小程序前端到后端的完整流程,包括验证码生成、发送、验证及用户信息提交等关键步骤。

在这里插入图片描述
才开始学习小程序,用到短信验证码登录,使用榛子云短信(smsow.zhenzikj.com)

微信小程序版SDK下载: http://smsow.zhenzikj.com/doc/sdk.html

最新的微信小程序注册demo大家也可以参看这个篇博客: https://blog.youkuaiyun.com/zuoliangzhu/article/details/85927146

效果:

我是java开发者,后端使用了springMvc

短信验证码实现流程
1、构造手机验证码,生成一个6位的随机数字串;
2、使用接口向短信平台发送手机号和验证码,然后短信平台再把验证码发送到制定手机号上
3、将手机号验证码、操作时间存入Session中,作为后面验证使用;
4、接收用户填写的验证码、手机号及其他注册数据;
5、对比提交的验证码与Session中的验证码是否一致,同时判断提交动作是否在有效期内;
6、验证码正确且在有效期内,请求通过,处理相应的业务。

小程序代码

info.wxml

<view class="container">
 
<view class="section">
<text>手机号码</text>
<input placeholder="请输入手机号码" type="number" maxlength="11" bindinput="inputPhoneNum" auto-focus />
<text wx:if="{{send}}" class="sendMsg" bindtap="sendMsg">发送</text>
<text wx:if="{{alreadySend}}" class="sendMsg" bindtap="sendMsg">{{second+"s"}}</text>
</view>
 
<view class="section">
<text>短信验证</text>
<input placeholder="短信验证码" type="number" bindinput="addCode" />
</view>
 
<view class="section">
<text>其他信息</text>
<input placeholder="需要提交的信息" bindinput="addOtherInfo" />
</view>
 
<button type="{{buttonType}}" disabled="{{disabled}}" bindtap="onSubmit">保存</button>
 
</view>

info.js

// info.js
const config = require('../../config/config.default.js')
 
Page({
  data: {
    send: false,
    alreadySend: false,
    second: 60,
    disabled: true,
    buttonType: 'default',
    phoneNum: '',
    code: '',
    otherInfo: ''
  },
  onReady: function () {
    wx.request({
      url: `${config.api + '/getSessionId.html'}`,
      header: { 
        "Content-Type": "application/x-www-form-urlencoded"
      },
      method: 'POST',
      success: function (res) {
        wx.setStorageSync('sessionId', 'JSESSIONID=' + res.data)
 
      }
    })
  },
// 手机号部分
  inputPhoneNum: function (e) {
    let phoneNum = e.detail.value
    if (phoneNum.length === 11) {
      let checkedNum = this.checkPhoneNum(phoneNum)
      if (checkedNum) {
        this.setData({
          phoneNum: phoneNum
        })
        console.log('phoneNum' + this.data.phoneNum)
        this.showSendMsg()
        this.activeButton()
      }
    } else {
      this.setData({
        phoneNum: ''
      })
      this.hideSendMsg()
    }
  },
 
  checkPhoneNum: function (phoneNum) {
    let str = /^1\d{10}$/
    if (str.test(phoneNum)) {
      return true
    } else {
      wx.showToast({
        title: '手机号不正确',
        image: '../../images/fail.png'
      })
      return false
    }
  },
 
  showSendMsg: function () {
    if (!this.data.alreadySend) {
      this.setData({
        send: true
      })
    }
  },
 
  hideSendMsg: function () {
    this.setData({
      send: false,
      disabled: true,
      buttonType: 'default'
    })
  },
 
  sendMsg: function () {
    var phoneNum = this.data.phoneNum;
    var sessionId = wx.getStorageSync('sessionId');
    wx.request({
      url: `${config.api + '/sendSms.html'}`,
      data: {
        phoneNum: phoneNum
      },
      header: {
        "Content-Type": "application/x-www-form-urlencoded",
        "Cookie": sessionId
      },
      method: 'POST',
      success: function (res) {
        console.log(res)
      }
    })
    this.setData({
      alreadySend: true,
      send: false
    })
    this.timer()
  },
 
  timer: function () {
    let promise = new Promise((resolve, reject) => {
      let setTimer = setInterval(
        () => {
          this.setData({
            second: this.data.second - 1
          })
          if (this.data.second <= 0) {
            this.setData({
              second: 60,
              alreadySend: false,
              send: true
            })
            resolve(setTimer)
          }
        }
        , 1000)
    })
    promise.then((setTimer) => {
      clearInterval(setTimer)
    })
  },
 
// 其他信息部分
  addOtherInfo: function (e) {
    this.setData({
      otherInfo: e.detail.value
    })
    this.activeButton()
    console.log('otherInfo: ' + this.data.otherInfo)
  },
 
// 验证码
  addCode: function (e) {
    this.setData({
      code: e.detail.value
    })
    this.activeButton()
    console.log('code' + this.data.code)
  },
 
 // 按钮
  activeButton: function () {
    let {phoneNum, code, otherInfo} = this.data
    console.log(code)
    if (phoneNum && code && otherInfo) {
      this.setData({
        disabled: false,
        buttonType: 'primary'
      })
    } else {
      this.setData({
        disabled: true,
        buttonType: 'default'
      })
    }
  },
 
  onSubmit: function () {
    var phoneNum = this.data.phoneNum;
    var code = this.data.code;
    var otherInfo = this.data.otherInfo;
    var sessionId = wx.getStorageSync('sessionId');
    wx.request({
      url: `${config.api + '/addinfo.html'}`,
      data: {
        phoneNum: phoneNum,
        code: code,
        otherInfo: otherInfo
      },
      header: {
        "Content-Type": "application/x-www-form-urlencoded",
        "Cookie": sessionId
      },
      method: 'POST',
      success: function (res) {
        console.log(res)
 
        if ((parseInt(res.statusCode) === 200) && res.data.message === 'pass') {
          wx.showToast({
            title: '验证成功',
            icon: 'success'
          })
        } else {
          wx.showToast({
            title: res.data.message,
            image: '../../images/fail.png'
          })
        }
      },
      fail: function (res) {
        console.log(res)
      }
    })
  }
})

需要注意的是小程序没有session的概念,所以我们需要虚拟出http的session:

  1. 在onReady获取服务器端的sessionId, 并存储到本地缓存中

  2. 每次发起http请求时在header中构造: “Cookie”: sessionId

服务器端代码

  1. 获取sessionId

    /**
    * 获得sessionId
    */
    @RequestMapping("/getSessionId")
    @ResponseBody
    public Object getSessionId(HttpServletRequest request) {
    try {
    HttpSession session = request.getSession();
    return session.getId();
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }

  2. 发送短信验证码

    /**
    * 发送短信验证码
    * @param number接收手机号码
    */
    @RequestMapping("/sendSms")
    @ResponseBody
    public Object sendSms(HttpServletRequest request, String phoneNum) {
    try {
    JSONObject json = null;
    //生成6位验证码
    String verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);
    //发送短信
    ZhenziSmsClient client = new ZhenziSmsClient(“你的appId”, “你的appSecret”);
    String result = client.send(phoneNum, “您的验证码为:” + verifyCode + “,该码有效期为5分钟,该码只能使用一次!【短信签名】”);
    json = JSONObject.parseObject(result);
    if(json.getIntValue(“code”) != 0)//发送短信失败
    return “fail”;
    //将验证码存到session中,同时存入创建时间
    //以json存放,这里使用的是阿里的fastjson
    HttpSession session = request.getSession();
    json = new JSONObject();
    json.put(“verifyCode”, verifyCode);
    json.put(“createTime”, System.currentTimeMillis());
    // 将认证码存入SESSION
    request.getSession().setAttribute(“verifyCode”, json);
    return “success”;
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }

  3. 提交信息并验证短信验证码

    /**
    * 注册
    */
    @RequestMapping("/addinfo")
    @ResponseBody
    public Object addinfo(
    HttpServletRequest request,
    String phoneNum,
    String code,
    String otherInfo) {
    JSONObject json = (JSONObject)request.getSession().getAttribute(“verifyCode”);
    if(!json.getString(“verifyCode”).equals(code)){
    return “验证码错误”;
    }
    if((System.currentTimeMillis() - json.getLong(“createTime”)) > 1000 * 60 * 5){
    return “验证码过期”;
    }
    //将用户信息存入数据库
    //这里省略
    return “success”;
    }

转载:http://smsow.zhenzikj.com/bbs/question/detail/40.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值