背景

通过手机短信发送验证码,是最普遍、最安全验证用户真实身份的方式。目前,短信验证码广泛应用于用户注册、密码找回、登录保护、身份认证、随机密码、交易确认等应用场景。

原理

短信验证的原理按步骤可分为6步:

构造手机验证码。使用random对象生成要求的随机数作为验证码,例如4位验证码:1000~9999之间随机数;
使用接口向短信平台发送手机号和验证码数据。然后短信平台再把验证码发送到制定手机号上,接口参数一般包括:目标手机号,随机验证码(或包含失效时间),平台接口地址,平台口令;
保存短信平台返回的信息。具体来说,将手机号、验证码和操作时间存入数据库,用于验证。
接收用户填写的验证码及其他数据。
对用户返回的数据和保存在数据库中的数据做匹配,同时判断提交动作是否在有效期内。
验证码正确且在有效期内,请求通过,处理相应的业务。
上述过程可以使用云函数和云数据库来实现。同时,考虑给云函数部署网关触发器,用户需要使用短信验证码服务时只需要往网关地址发送附带用户信息的请求。

详细方案

首先需要配置好云函数和云数据库,其中云函数和云数据库需要处于同一个VPC下,以便云函数能够直接访问云数据库。

接着创建一个简单的hello world函数模板并给该函数赋予访问腾讯短信平台的权限,即需要在到访问管理控制台给 SCF_QcsRole 角色添加短信 QcloudSMSFullAccess 权限。

接着编写代码实现短信验证逻辑,这里以nodejs为例子。

/**************************************************
* 功能:1.发送短信 2.登录(校验短信验证码)
* 函数运行的前提条件:
1.创建模板函数后,请先添加函数运行角色,并给该角色关联短信QcloudSMSFullAccess权限。
2.本服务用到redis存储验证码,请先申请redis资源,并将redis的host和密码设置成环境变量。
3.去云短信控制台申请短信模板和签名
* 详细请参考:https://github.com/tencentyun/scf-demo-repo/tree/master/Nodejs8.9-SmsVerificationCode
***************************************************/'use strict';
const redis = require('ioredis');
const tencentcloud = require('tencentcloud-sdk-nodejs');
const queryParse = require('querystring')
const expireTime = 5 * 60;//验证码有效期5分钟exports.main_handler = async (event, context, callback) => {let queryString = event.queryString // get形式if(event.httpMethod === "POST") { // post形式queryString = queryParse.parse(event.body)}if(!queryString || !queryString.method || !queryString.phone) {return {codeStr: 'InValidParam',msg: "缺少参数"}}const redisStore = new redis({port: 6369, // Redis instance port, redis实例端口host: process.env.REDIS_HOST, // Redis instance host, redis实例hostfamily: 4,password: process.env.REDIS_PASSWORD, // Redis instance password, redis实例密码db: 0});if(queryString.method === "getSms") {return await getSms(queryString, redisStore)} else if(queryString.method === "login") {return await loginSms(queryString, redisStore)}
}/*
* 功能:登录,校验验证码
*/
async function loginSms(queryString, redisStore) {if(!queryString.code) {return {codeStr: 'MissingCode',errorMessage: "缺少验证码参数"}}const redisResult = await redisPromise(redisStore, queryString)if(!redisResult) {//没有找到记录return {codeStr: 'CodeHasExpired',msg: "验证码已过期"}}let result = JSON.parse(redisResult)if(!result || result.used || result.num >= 3) {return {codeStr: 'CodeHasValid',msg: "验证码已失效"}}if(result.code == queryString.code) { //验证码校验正确updateRedis(redisStore, queryString.phone, result, true) //将验证码更新为已使用// 验证码校验通过,执行登录逻辑console.log('校验验证码成功')return {codeStr: 'Success',msg: '校验验证码成功'}} else { // 验证码校验失败updateRedis(redisStore, queryString.phone, result, false)return {codeStr: 'CodeIsError',msg: "请检查手机号和验证码是否正确"}}
}
// 更新redis状态
function updateRedis(redisStore, phone, result, used) {const sessionCode = {code: result.code,sessionId: result.sessionId,num: ++result.num, //验证次数,最多可验证3次used: used //true-已使用,false-未使用}redisStore.set('sms_' + phone, JSON.stringify(sessionCode));if(used) {redisStore.expire('sms_' + phone, 0);} else {redisStore.expire('sms_' + phone, expireTime);}
}
/** 功能:根据手机号获取短信验证码*/
async function getSms(queryString, redisStore) {const code = Math.random().toString().slice(-6);//生成6位数随机验证码const sessionCode = {code: code,num: 0, //验证次数,最多可验证3次used: false //false-未使用,true-已使用}redisStore.set('sms_' + queryString.phone, JSON.stringify(sessionCode));redisStore.expire('sms_' + queryString.phone, expireTime);let queryResult = await sendSms(queryString.phone, code)return queryResult
}
/** 功能:通过sdk调用短信api发送短信* 参数 手机号、短信验证码*/
async function sendSms(phone, code) {const SmsClient = tencentcloud.sms.v20190711.Client;const Credential = tencentcloud.common.Credential;const ClientProfile = tencentcloud.common.ClientProfile;const HttpProfile = tencentcloud.common.HttpProfile;const secretId = process.env.TENCENTCLOUD_SECRETID;const secretKey = process.env.TENCENTCLOUD_SECRETKEY;const token = process.env.TENCENTCLOUD_SESSIONTOKEN;let cred = new Credential(secretId, secretKey, token);let httpProfile = new HttpProfile();httpProfile.endpoint = "sms.tencentcloudapi.com";let clientProfile = new ClientProfile();clientProfile.httpProfile = httpProfile;let client = new SmsClient(cred, "ap-guangzhou", clientProfile);let req = {PhoneNumberSet: ["+" + phone], //大陆手机号861856624****TemplateID: process.env.SMS_TEMPLATE_ID, //腾讯云短信模板idSign: process.env.SMS_SIGN, //腾讯云短信签名TemplateParamSet: [code],SmsSdkAppid: process.env.SMS_SDKAPPID //短信应用id}let queryResult = await smsPromise(client, req)return queryResult
}async function smsPromise(client, req) {return new Promise((resolve, reject) => {client.SendSms(req, function(errMsg, response) {if (errMsg) {reject(errMsg)} else {if(response.SendStatusSet && response.SendStatusSet[0] && response.SendStatusSet[0].Code === "Ok") {resolve({codeStr: response.SendStatusSet[0].Code,msg: response.SendStatusSet[0].Message})} else {resolve({codeStr: response.SendStatusSet[0].Code,msg: response.SendStatusSet[0].Message})}}                });})
}async function redisPromise(redisStore, queryString) {return new Promise((res, rej) => {redisStore.get('sms_' + queryString.phone, function (err, result) {if (err) {rej(err)}res(result)});})
}
接着就可以测试了。

使用云函数构建短信验证码服务的案例相关推荐

  1. 基于阿里云平台的短信验证码服务API的使用

    基于阿里云平台的短信验证码服务API的使用 第一步:登录阿里云平台 第二步:申请国内文本短信签名 如果是个人作业项目(如作者的签名),可以直接申请测试和学习用的测试签名,该签名的缺点是必须绑定测试手机 ...

  2. egg.js 调用阿里云(阿里大于)短信验证码服务

    1.开通阿里云短信服务 阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台 可以免费申请 企业短信验证码 200条 重点是: 签名名称:接收验证码内容时,[]里的文字. 短信模板code:相当于 ...

  3. java微信发送验证码,详解如何使用微信小程序云函数发送短信验证码

    其实微信小程序前端和云端都是可以调用短信平台接口发送短信的,使用云端云函数的好处是无需配置域名,也没有个数限制. 1.安装 下载后的SDK在cloudfunctions文件夹下会包含3个云函数文件夹, ...

  4. 腾讯云发送短信验证码服务

    腾讯云发送短信验证码服务 1.注册腾讯云的账号 在腾讯云的官网:https://cloud.tencent.com/注册一个腾讯云的账号,就是日常的注册流程(这里就不贴图了),不过要实名认证啥的,认证 ...

  5. 使用腾讯云模板发送短信验证码

    目录 学习目标: 学习内容: 学习时间: 学习过程: demo结构图: 效果图: 配置准备: 依赖pom.xml application.properties: application.yml 腾讯云 ...

  6. node.js实现阿里云配置发送短信验证码

    目录 开始 签名添加 模板添加 测试短信 项目中使用 Core accessKeyId | accessKeySecret params PhoneNumbers SignName TemplateC ...

  7. 基于阿里云的手机短信验证码和注册校验逻辑

    基于阿里云的手机短信验证码demo实现 1. 环境依赖 2. 页面表单 html 3. 校验与短信 js 4. 工具类 SmsUtils 5. 资源调用 Servlet 阿里云的短信平台:http:/ ...

  8. 阿里和云之讯短信发送服务

    目录 1 云之讯短信验证码 1.1 创建应用 1.2 创建短信模板 1.3 发送短信api 1.4 编写代码 1.5 编写测试用例 1.6 编写接口服务 2 阿里云短信服务 2.1 申请签名与模板 2 ...

  9. 基于redis的短信验证码服务开发

    基于redis的短信验证码服务开发 目前可以提供的验证码服务平台有很多,这里选择阿里大于短信验证码服务平台,里面有10元体验卷可以免费试用,不多说上代码.写代码之前需要去阿里大于平台申请验证码服务,同 ...

最新文章

  1. 【Codeforces】1015B Obtaining the String(字符串 交换)
  2. XML Tree(树形结构)
  3. “编程能力差的程序员,90%输在了这点上!”谷歌AI专家:都是瞎努力!
  4. ERROR: Cannot uninstall ‘PyYAML‘. 安装 fvcore
  5. Git --- 傻瓜内容跟踪器
  6. Could not connect to SMTP host: smtp.qq.com, port: 465, response: -1 clojure邮箱发送
  7. Delphi 2007 TIDHttp HTTPS 出现Error connecting with SSL
  8. 游戏数据分析方法-活跃向
  9. Linux下安装JDK常用命令
  10. 楼梯计算机公式,楼梯踏步数计算公式是什么
  11. SQLServer中定义拼音检索函数,根据中文参数返回对应汉字的拼音首字母
  12. 【CZY选讲·吃东西】
  13. CRM系统中的线索、客户、联系人、商机
  14. 安卓手机APP 开发
  15. logistic回归模型总结
  16. 定时器中断实验和PWM输出实验(寄存器)
  17. Android界面开发
  18. Cookie、session以及localStorage与sessionStorage之间的区别
  19. 10款PHP开源的外贸网店电子商务管理系统
  20. Jquery参考手册免费下载

热门文章

  1. 科技新品 | 军规级户外运动智能手表;本田赛车合作款金属计时表;富士影像数字印刷设备...
  2. 一款修改字体(简繁转换)
  3. 预告——看我出招之:苦战samba乱码
  4. Google三驾马车:GFS、MapReduce和Bigtable
  5. IFIX所有版本的操作系统支持
  6. 超强综述 | Rob Knight等手把手教你分析菌群数据(全文翻译1.8万字)
  7. 美国DOE认证及美国授权代理
  8. 智慧工厂实施建设方案-数字化
  9. 配置VirtualBox虚拟机
  10. (29)打鸡儿教你Vue.js