一.阿里云开通短信服务功能
1.申请短信签名

2.申请短信模板
3.获得AccessKey 和AccessKey Secret
4.购买短信套餐包
二.前端页面
三.后端Flask接口
1.安装SDK依赖包
pip install aliyun-python-sdk-dysmsapi==2.1.1
2.发送验证码与验证验证码
# -*- coding: utf-8 -*-
# @Time : 2021/11/7 9:22
# @Author : 张亚礼
# @FileName: register
from flask import render_template, request, jsonify
from bluprints.user import user_bp
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
from aliyunsdkcore.auth.credentials import AccessKeyCredential
from aliyunsdkcore.auth.credentials import StsTokenCredential
import json
import random
from nosql_connection import redisConnection
#检验及注册
@user_bp.route("/api/register",methods=["GET","POST"])
def register():
#获取用户输入的验证码
yzcode = request.form.get("yzcode")
#获取用户手机号
phone = request.form.get("phone")
# 连接redis数据库
con = redisConnection(1)
if con.exists(phone)==0:
return jsonify({"mes":"验证码已失效"})
else:
redis_yzcode = con.get(phone)
if yzcode==redis_yzcode:
#验证成功删除缓存的验证码
con.delete(phone)
return jsonify({"mes":'验证成功'})
else:
return jsonify({"mes":"验证码错误"})
#获得验证码
@user_bp.route("/api/getCode",methods=["GET","POST"])
def getCode():
phone = request.form.get("phone")
#生成6位随机验证码
verificationCode = ""
for item in range(6):
intNum = random.randint(0, 9)
strNum = str(intNum)
verificationCode += strNum
params = {
"code": verificationCode
}
#连接redis数据库
con = redisConnection(1)
#将验证码存入redis数据库,并设置键过期时间5分钟
con.setex(phone,300,verificationCode)
credentials = AccessKeyCredential('LTAI5tQoMrnEQF8YdaWv6rw2', 'IZsP9sjfTo552jHpXbIYZql40bhkeT')
# use STS Token
# credentials = StsTokenCredential('<your-access-key-id>', '<your-access-key-secret>', '<your-sts-token>')
client = AcsClient(region_id='cn-shanghai', credential=credentials)
req = CommonRequest()
req.set_accept_format('json')
req.set_domain('dysmsapi.aliyuncs.com')
req.set_method('POST')
req.set_protocol_type('https') # https | http
req.set_version('2017-05-25')
req.set_action_name('SendSms')
req.add_query_param('PhoneNumbers', phone) # 目标手机号
req.add_query_param('TemplateCode', "SMS_227745922") # 短信模板ID
req.add_query_param('SignName', "鸭梨网") # 短信签名
# ${code}的赋值,json格式
req.add_query_param('TemplateParam', json.dumps(params))
res = client.do_action(req)
# print(str(res, encoding='utf-8'))
return jsonify({"mes":"successful"})
redis连接
//nosql_connection.py
import redis
REDIS_HOST = "106.14.107.75"
REDIS_PORT = 6379
REDIS_AUTH = "123456"
def redisConnection(databaseNum):
pool = redis.ConnectionPool(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_AUTH, db=databaseNum, decode_responses=True)
mycon = redis.Redis(connection_pool=pool)
return mycon
前端源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<title>Document</title>
<style>
.card{
width: 400px;
height: auto;
}
.margin{
margin-top: 20px;
}
.card{
border-radius: 20px;
}
.container{
display: flex;
justify-content:center;
align-items: center;
margin-top: 200px;
}
.flex{
display: flex;
justify-content: space-between;
}
.card{
width: 400px;
height: auto;
}
.margin{
margin-top: 20px;
}
.card{
border-radius: 20px;
}
.container{
display: flex;
justify-content:center;
align-items: center;
margin-top: 200px;
}
h2{
font-weight: lighter;
}
.radio{
margin-top: 30px;
}
.font{
font-size: 13px;
color: darkgray;
}
.flex{
display: flex;
justify-content: space-between;
}
#exampleFormControlSelect1{
width: 80px;
}
#check{
width: 150px;
margin-right: 20px;
}
.display{
display: none;
}
.error{
color: red;
font-size: 14px;
}
.error-border{
border: 1px solid red;
}
</style>
<script type="text/javascript">
$(document).ready(()=>{
pattern = /^1[3456789][0-9]{9}$/;
time=60;
$("#tel").focus(()=>{
$('#tel-slot').empty();
$('#tel').removeClass("error-border");
}).blur(()=>{ //手机号码框验证
if($('#tel').val()==""){
$('#tel-slot').text("手机号不能为空").addClass("error");
$('#tel').addClass("error-border");
}else
if(!pattern.test($('#tel').val())){
$('#tel-slot').text("手机格式有误!").addClass("error");
$('#tel').addClass("error-border");
}
}).keyup(function(){
if(pattern.test($('#tel').val())){
$('#getCheck').removeAttr("disabled").addClass("btn-primary").removeClass("btn-secondary");
}else{
$('#getCheck').attr("disabled","disabled").removeClass("btn-primary").addClass("btn-secondary");
}
});
$("#getCheck").click(()=>{
$('#getCheck').attr("disabled","disabled").addClass("btn-secondary");
id=setInterval(function(){
if(time==1){
clearInterval(id);
time=60;
$('#getCheck').removeAttr("disabled").removeClass("btn-secondary");
$('#getCheck').val("发送短信验证码");
}else{
$('#getCheck').val("重发验证"+"("+(--time)+"s)");
}
},1000);
})
$("#check").focus(()=>{
$('#check-slot').empty();
$('#check').removeClass("error-border");
}).blur(()=>{
if($("#check").val()=""){
$('#check-slot').text("验证码不能为空").addClass("error");
$('#check').addClass("error-border");
}
})
// 获得验证码
$("#getCheck").click(()=>{
var telphone = $("#tel").val();
$.post("http://localhost:5000/api/getCode",{
"phone":telphone
},function(data,status){})
});
// 点击注册验证
$("form").submit(function(e){
var check = $("#check").val();
var phone = $("#tel").val();
if(check==""){
e.preventDefault();
$('#check-slot').text("验证码不能为空").addClass("error");
$('#check').addClass("error-border");
} else {
$.post("http://localhost:5000/api/register",{
"yzcode":check,
"phone":phone
},function(data,status){
alert(data)
})
}
})
})
</script>
</head>
<body class="container bg-primary">
<div class="card bg-white">
<div class="card-body">
<h1>欢迎注册</h1>
<div class="margin">
<div>已有账号?<span> <a href="http://www.yaliwiki.com">登录</a></span></div>
</div>
<form action="http://localhost:5000/api/register" method="post">
<div class="margin">
<input type="text" class="form-control" placeholder="手机号码" id="tel" value="" name="phone">
</div>
<div id="tel-slot"></div>
<div class="margin">
<div class="flex margin ">
<input type="text" class="form-control" placeholder="验证码" id="check" value="" name="yzcode">
<input type="button" class="btn btn-secondary btn-block" id="getCheck" value="发送短信验证码" disabled="disabled"></input>
</div>
<div id="check-slot"></div>
</div>
<input type="submit" class="btn btn-primary btn-block margin" id="register" value="立即注册"/>
</form>
</div>
</div>
</body>
</html>