【NodeJS】 API Key 实现 短信验证码功能

这里使用的平台是 短信宝
整体来讲还是挺麻烦的平台必须企业才行,个人是无法使用该平台的
平台必须完成 身份信息认证 和 企业认证
 这里就需要 “营业执照”了 ,没有 “营业执照” 的朋友还是后退一步吧

后端我用的是NodeJS ,使用第三方库 router 来制作 api访问地址接口,然后在 验证码api 访问地址接口内“ 使用 axios 向 “https://api.smsbao.com/sms” 发送请求 ” ,当用户访问这个地址就执行,最后把失败或成功的值返回给前端 ,然后在做一个post接口,用来核对用户填写的验证码是否和发生至 接收手机号 的短信验证码一致 ,成功返回什么 ? 失败返回什么? 就这样 !
 

import express from 'express'
const router = express.Router()
import axios from 'axios'
// 替换为你的API账号信息
const apiUsername = 'your account number'
const apiPassword = 'your password md5'
const apiUrl = 'https://api.smsbao.com/sms'

// 发送短信验证码的函数
async function sendSMS (mobile, content) {
  try {
    // `https://api.smsbao.com/sms?u=${apiUsername}&p=${apiPassword}&m=${mobile}&c=${content}`
    const response = await axios.get(apiUrl, {
      params: {
        u: apiUsername, //用户名
        p: apiPassword, //密码
        m: mobile,     //手机号
        c: content     //短信发送内容
      }
    })
    // 处理响应,根据需要进行进一步的处理
    console.log('SMS Sent:', response.data)
    return response.data
  } catch (error) {
    console.error('Error sending SMS:', error)
    throw error
  }
}

function generateRandomCode (length) {
  const min = Math.pow(10, length - 1)
  const max = Math.pow(10, length) - 1
  return Math.floor(Math.random() * (max - min + 1) + min).toString()
}

//存储验证码
let mobileCodeNumber

//发送验证码
router.get('/Test/MobileCodeNumber', async (req, res) => {
  console.log(`这是用户传递来的信息`, req.query)

  if (!req.query.mobile)
    return res.status(400).json({ code: 400, message: 'mobile参数必传' })
  try {
    const mobileNumber = req.query.mobile // 替换为实际的手机号码
    const verificationCode = generateRandomCode(6) // 生成或获取实际的验证码
    console.log(`验证码`, verificationCode)
    await sendSMS(
      mobileNumber,
      `【短信宝】您的验证码是${verificationCode},30秒内有效`
    )
    mobileCodeNumber = verificationCode
    res.status(200).json({ code: 200, message: 'SMS sent successfully!' })
  } catch (error) {
    console.error(error)
    res.status(400).json({ code: 400, message: 'Failed to send SMS.' })
  }
})

//核对用户填写验证码是否和接收到的一致
router.post('/Test/login', async (req, res) => {
  if (req.body.code == mobileCodeNumber) {
    res.status(200).send({ code: 200, message: '登录成功' })
  } else {
    res.status(400).send({ code: 400, message: '验证码错误' })
  }
})
export default router

前端V3简单做了一下样式功能

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./style/vant@3.css" />
    <title>Document</title>
</head>

<body>
    <div id="mobileCodeNumber">
        <van-cell-group inset>
            <van-field v-model="mobile" type="tel" label="手机号"></van-field>
            <van-field v-model="mobileCode" center clearable label="短信验证码" placeholder="请输入短信验证码">
                <template #button>
                    <van-button size="small" type="primary" :disabled="counting" @click="sendSms">
                        {{ counting ? `${count}s 后重新发送` : '发送验证码' }}
                    </van-button>
                </template>
            </van-field>
            <van-button round block type="success" @click="GotoLogin">登录</van-button>
        </van-cell-group>
    </div>
    <script src="https://gitee.com/just-once-1/utils/tree/master/utils/Vue3.js"></script>
    <script src="https://gitee.com/just-once-1/utils/tree/master/utils/vant.min.js"></script>
    <script src="https://gitee.com/just-once-1/utils/tree/master/utils/axios.js"></script>
    <script src="https://gitee.com/just-once-1/utils/tree/master/utils/VantPlugin.js"></script>
    <script>
        const { createApp, ref } = Vue;
        const mobile = ref('')
        const counting = ref(false)
        const count = ref(60)
        const mobileCode = ref('')
        let domain = 'http://127.0.0.1:3009'
        const app = createApp({
            data() {
                return {
                    mobile,
                    counting,
                    count,
                    mobileCode
                }
            },
            setup() {
                const sendSms = () => {
                    if (!counting.value) {
                        counting.value = true;
                        useSendMobileCode()
                        const timer = setInterval(() => {
                            if (count.value > 0) {
                                count.value--;
                            } else {
                                counting.value = false;
                                count.value = 60;
                                clearInterval(timer);
                            }
                        }, 1000);
                    }
                };
                const useSendMobileCode = async () => {
                    try {
                        const res = await axios({
                            url: domain + `/Test/MobileCodeNumber?mobile=${mobile.value}`,
                            method: 'get'
                        })
                        console.log(': ', res)
                    } catch (err) {
                        console.log(': ', err.response)
                    }
                }

                const GotoLogin = async () => {
                    try {
                        const res = await axios({
                            url: domain + '/Test/login',
                            method: 'post',
                            data: {
                                mobile: mobile.value,
                                code: mobileCode.value
                            }

                        })
                        console.log('GotoLogin: ', res)
                    } catch (err) {
                        console.log('GotoLogin: ', err.response)
                    }
                }
                return {
                    sendSms,
                    useSendMobileCode,
                    GotoLogin
                };
            },

        });

        app.use(VantPlugin);

        app.mount('#mobileCodeNumber');
    </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/206569.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

连接mysql 出现can‘t connect to server on ‘localhost‘ (10061) 报错

首先确保你自己已经安装了mysql。 如果安装了mysql 还是有问题。我们可以在 任务管理器 》服务 中找Mysql服务。 如果有Mysql 服务&#xff0c;启动服务即可。 如果没有这个服务&#xff0c;需要我们下载服务。具体操作如下 管理员启动终端&#xff0c;找到安装的mysql &…

转战MySQL Shell!数据库备份新姿势,轻松搞定备份操作!

MySQL8.0后续版本中主推使用MySQL Shell进行相关日常管理及维护操作&#xff0c;如果后续移除了mysqldump等命令后&#xff0c;如何进行数据库备份等相关操作呢&#xff1f;本文开始进行数据库备份的操作。 1. MySQL Shell 安装 1.1 下载 可以在MySQL官网进行下载&#xff0…

分布式系统:CAP 定理

欢迎来到分布式系统系列。在本文中&#xff0c;我们将学习并理解什么是 CAP 定理。CAP 代表一致性、可用性和分区容错性。当我们谈论CAP定理时&#xff0c;我们主要谈论的是分布式系统。首先&#xff0c;让我们了解一下什么是分布式系统。分布式系统是由运行在单台或多台机器上…

【驱动】串口驱动分析(一)-软件架构

区分不同的终端类型 串行端口终端&#xff08;/dev/ttySn&#xff09; 串行端口终端&#xff08;Serial Port Terminal&#xff09;是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。 有段时间这些串行端口设备通常被称为终端设备&#xff0…

Redis哈希对象(listpack介绍)

哈希对象的编码可以是ziplist或者hashtable。再redis5.0版本之后出现listpack&#xff0c;为了是代替ziplist。 一. 使用ziplist编码 ziplist编码的哈希对象使用压缩列表作为底层实现&#xff0c;每当有新的键值对要加入到哈希对象时&#xff0c;程序都会先将保存了键值对的键…

el-table实现动态表头

1.1el-table渲染 <el-tableref"refreshTable":data"tableData"highlight-current-row><el-table-columnfixedwidth"170px"label"测点"align"center"prop"测站名称"/><el-table-column label"…

万户ezOFFICE wpsservlet任意文件上传漏洞复现

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品&#xff0c;统一的基础管理平台&#xff0c;实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台&#xff0c;将外网信息…

位图和布隆过滤器(C++)

位图和布隆过滤器 一、位图1. 引入2. 概念3. 代码实现setreset完整代码 4. 位图的应用 二、布隆过滤器1. 引入2. 概念3. 逻辑结构4. 特点5. 代码实现6. 布隆过滤器的应用 三、哈希切割 一、位图 1. 引入 当面对海量数据需要处理时&#xff0c;内存不足以加载这些数据&#xf…

C语言二叉树与堆的实现(一)

目录 二叉树 二叉树的分类&#xff08;目前只谈两种&#xff09; 满二叉树 完全二叉树 二叉树的性质&#xff08;其余的可以自己总结&#xff09; 选择练习 二叉树的存储结构 顺序存储方式 链式存储方式 一种完全二叉树&#xff1a;堆 堆的概念 堆的性质 建堆的时…

Windows本地搭建Emby媒体库服务器并实现远程访问「内网穿透」

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

OpenCvSharp从入门到实践-(06)创建图像

目录 1、创建图像 1.1实例1-创建黑色图像 1.2实例2-创建白色图像 1.3实例3-创建随机像素的雪花点图像 2、图像拼接 2.1水平拼接图像 2.2垂直拼接图像 2.3实例4-垂直和水平两种方式拼接两张图像 在OpenCV中&#xff0c;黑白图像其实就是一个二维数组&#xff0c;彩色图像…

GCN01——Ubuntu中设置vivado编辑器为vscode

确定vscode位置 在命令行中输入 which code得到文件地址 进入文件夹后可看到&#xff0c;这是个链接文件&#xff0c;不过无所谓&#xff0c;就用这个地址就行 设置Text Editor 打开setting选择右侧text editor 这里说明了如何进行设置 将自己的地址加进去就行 /usr/share…

Springboot快速整合kafka

kafka的基本了解 kafka也是 目前常用的消息中间件,支持同步与异步通信,和rabbitmq一样,工作模式大概相同,并且被spingboot整合的后的都是 中间件Template的实列化客户端类 ,消费者监听注解为KafkaListener,和RabbitListener和很相似,这些消息中间件使用过后,发现大致都是相同的…

SS6811H38V/1.6A 两通道 H 桥驱动芯片

SS6811H 为舞台灯光和其它电机一体化应用 提供一种双通道集成电机驱动方案。SS6811H 有 两路 H 桥驱动&#xff0c;每个 H 桥可提供最大输出电流 1.6A (在 24V 和 Ta 25C 适当散热条件下)&#xff0c;可驱 动两个刷式直流电机&#xff0c;或者一个双极步进电机&#xff0c;或 …

【shell】shell脚本编程作业

1 编写bash脚本&#xff0c;要求用户输入源目录和目标目录(绝对路径&#xff09;&#xff0c;然后列出源目录下所有的文件&#xff0c;并将这些文件拷贝到目标目录&#xff0c;并在文件名后面加上时间戳。&#xff08;提交源代码和运行截图&#xff09; if [ -d $1 ] || [ -d…

The Sandbox 携手 Sandsoft,与 Nuqtah 合作推动沙特阿拉伯的 Web3 发展

新的合作伙伴关系将增强创作者的能力&#xff0c;促进区块链生态系统的包容性。 The Sandbox 及其合作伙伴 Sandsoft 是移动游戏开发商和发行商&#xff0c;也是 AAA 人才驱动的投资者&#xff0c;他们非常高兴地宣布与 Nuqtah 建立新的合作伙伴关系&#xff0c;Nuqtah 是中东和…

SQL Sever 复习笔记【一】

SQL Sever 基础知识 一、查询数据第1节 基本 SQL Server 语句SELECT第2节 SELECT语句示例2.1 SELECT - 检索表示例的某些列2.2 SELECT - 检索表的所有列2.3 SELECT - 对结果集进行筛选2.4 SELECT - 对结果集进行排序2.5 SELECT - 对结果集进行分组2.5 SELECT - 对结果集进行筛选…

⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)

1.这里我代码没啥问题~~~编辑器里也没毛病 void Start(){// 加载底图和上层图片string backgroundImagePath Application.streamingAssetsPath "/background.jpg";Texture2D backgroundTexture new Texture2D(2, 2);byte[] backgroundImageData System.IO.File.R…

ClassNotFoundException: org.apache.hive.spark.client.Job

hive使用的是3.13版本&#xff0c;spark是3.3.3支持hadoop3.x hive将engine从mr改成spark&#xff0c;通过beeline执行insert、delete时一直报错&#xff0c;sparkTask rpc关闭&#xff0c; 查看yarn是出现ClassNotFoundException: org.apache.hive.spark.client.Job。 开始…

Flutter应用程序加固的问题及解决方案

​&#x1f680;Flutter应用程序加固的问题及解决方案引言在移动应用开发中&#xff0c;为了保护应用程序的安全性&#xff0c;开发者需要对应用进行加固。在使用Flutter技术进行应用程序开发时&#xff0c;也需要注意应用程序的安全问题和加固方案。本文将介绍在Flutter应用程…