使用nodejs接入封装第三方短信验证码工具类

简介:使用nodejs接入封装第三方短信验证码工具类

  • 第三方短信运营商接入

    • 安装axios
      yarn add axios@1.1.3
      
  • 配置

    • 在项目的config文件夹新建一个文件,命名为接入短信验证码平台的名字,例如aliyunMessage.js,具体配置如下
      	const axios = require('axios')
      	const sendMsgCode = (phone,randomCode) => {
              
              
      		return axios({
              
              
         		 	method:'post',
         			url:`http(s)://jmsms.market.alicloudapi.com/sms/send`,  //短信验证码平台接入的url
          		data:{
              
              
              		appid:'ATB3w4hJl7xqs9P2ty',   //appid可以在开通的短信验证码平台控制台即可查到
             			appSecret:'J5ByBB287o1Cipvc01U2eOgV0diXYuT8',  // appSecret可以在开通的短信验证码平台控制台即可查到
              		code:randomCode,  //要发送的随机数,需要自己定义
              		phoneNum:phone,  // 接收短信验证码的手机号
              		templateCode: "SMS_168781429"  // 额外的参数,需要结合短信验证码平台来编写,如不需要去掉即可
          		}
      		})
      	}
      	// 测试调试发送短信
      	(async()=>{
              
              
      		console.log((await sendMsgCode(13800138000,'5201')).data);
      	})()
      	// 进行导出
      	module.exports = sendMsgCode;
      
  • 随机生成四位数封装(路径:utils/randomTool.js)

    class RandomTool{
          
          
    	static randomCode(){
          
          
        	return Math.floor(Math.random()*(9999-1000)+1000)
    	}
    }
    module.exports = RandomTool
    
  • 数据层代码逻辑

    • 优化方案(方案二)
      • 必须保证两个redis操作的原子性:事务具有原子性指的是,数据库将事务中的多个操作当作一个整体来执行,服务器要么就执行事务中的所有操作,要么就一个操作也不执行。
      • 同时减少命名空间的浪费
            // 获取手机验证码逻辑处理
        sendCode: async (phone,captcha,type,key,randomCode) =>{
                  
                  
            // 60秒内不能重新获取
            // ------>方案一
            // if(await redisConfig.exists(`${type}:over:`+phone)) {
                  
                  
            //     return { code: -1, msg: '60秒内不能重复获取'}
            // }
        
            // ------->方案二
            if(await redisConfig.exists(`${
                    
                    type}:code:`+phone)){
                  
                  
                let dateRedis = dayjs(Number((await redisConfig.get(`${
                    
                    type}:code:`+phone)).split('_')[0]))
                if(dayjs(Date.now()).diff(dateRedis,'second')<=60) {
                  
                  
                    return {
                  
                  code:-1,msg:'60秒内不能重复获取'}
                }
            }
        
            // 是否已经填写图形验证码
            if (!(await redisConfig.exists(`${
                    
                    type}:captcha:`+key))) {
                  
                  
                return {
                  
                   code: -1, msg: '请发送图形验证码' }
              }
        
            // 对比用户的图形验证码和redis缓存中的是否一致
            let captchaRedis = await redisConfig.get(`${
                    
                    type}:captcha:`+key)
            if(!(captcha.toLowerCase() === captchaRedis.toLowerCase())) {
                  
                  
                return {
                  
                   code: -1,msg:'图形验证码填写错误'}
            }
        
            // 发送手机验证码
            let CodeRes = (await aliyunMessage(phone,randomCode)).data
            
            // ------->方案一
            // // 验证码存入redis
            // redisConfig.set(`${type}:code`+phone,randomCode,600)
        
            // // 存60秒判断
            // redisConfig.set(`${type}:over:`+phone,'1',60)
        
            // ------->方案二
            // 获取当前时间拼接验证码
            let randomCodeTime = `${
                    
                    Date.now()}_${
                    
                    randomCode}`
            redisConfig.set(`${
                    
                    type}:code:`+phone,randomCodeTime,600)
        
            // 删除图形验证码
            redisConfig.del(`${
                    
                    type}:captcha:`+key)
        
            if(CodeRes.code == 0) return {
                  
                  code:0,msg:'验证码发送成功'}
            else {
                  
                  return {
                  
                  code:-1,msg:'验证码发送失败'}}
        }
        
  • 对用户的ip和设备进行md5加密,文件路径:controller/NotifyController.js

    const NotifyService = require('../service/NotifyService')
    const GetUserInfoTool = require('../utils/GetUserInfoTool')
    const SecretTool = require('../utils/SecretTool')
    const randomTool = require('../utils/randomTool')
    
    const NotifyController = {
          
          
        sendCode: async(req,res)=>{
          
          
            let {
          
          phone,captcha,type}  = req.body;
            // 用户的ip+设备md5加密
            let _key = SecretTool.md5(GetUserInfoTool.getIp(req)+GetUserInfoTool.getUserAgent(req))
            let handleRes = await NotifyService.sendCode(phone,captcha,type,_key,randomTool.randomCode())
            res.send(handleRes)
        }
    }
    
    module.exports = NotifyController
    
  • 在router文件夹里面编写接口路径,以及调用的方法

    const express = require('express')
    const router = express.Router()
    const NotifyController = require('../controller/NotifyController')
    
    // 图形验证码接口
    router.get('/captcha',NotifyController.captcha)
    
    // 手机验证码接口
    router.post('/sendCode',NotifyController.sendCode)
    
    module.exports = router
    
  • 大功告成,可以在apifox上进行调用,需要先请求图形验证码接口,图形验证码如何编写可以看我以往的文章
    在这里插入图片描述

  • 手机上也收到了对应的短信验证码
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u011313034/article/details/131040808