集成第三方发送短信

介绍

用户登录

用户登录有两种方式: 短信登录,密码登录

短信登录是使用手机号和验证码进行登录

短信平台

很多云平台,比如阿里云,腾讯云,七牛云等云厂商,向程序开发者提供了短信验证码套餐服务。借助云平台的短信服务,程序开发者可以非常简单方便的将短信服务集成到自己的程序中。

我们以接入和集成阿里云的短信服务sdk为例, 如果需要申请腾讯云短信服务可以看我另外写的一篇blog,使用两者都差不多

https://www.cnblogs.com/you-men/p/13088949.html

阿里云短信服务集成-登录阿里云

登录阿里云

登录阿里云:https://www.aliyun.com/

选择短信服务模块:https://www.aliyun.com/product/sms

注明:云平台的短信服务是收费的,有不同类别的套餐。开发者可以按照自己的需求进行选择。如下图:

Go短信服务SDK

可以访问https://api.aliyun.com/?spm=5176.12207334.0.0.54d71cbe3NE29f#/?product=Dysmsapi&lang=GO查看go语言版本的短信服务sdk代码。

安装阿里云GO SDK
go get github.com/aliyun/alibaba-cloud-sdk-go
创建签名和短信模板

在使用go sdk集成短息服务之前,需要首先创建短信签名和短信模板。

签名:短信签名是短信服务提供的一种快捷、方便的个性化签名方式。当发送短信时,短信平台会根据设置,在短信内容里附加个性签名,再发送给指定手机号码。比如,下图红框中的"招商银行”就是这条短信的签名,用以标识发送者的类别等内容。

在阿里云后台的短信服务控制面板的左侧功能栏中,选择国内消息,如下图所示,然后选择签名管理的TAB,然后选择添加签名,可以创建新的短信签名。如下图:

短信模板:短信模版,即具体发送的短信内容。短信模版可以支持验证码、短信通知、推广短信三种模式。验证码和短信通知,通过变量替换实现个性短信定制。

与创建签名同理,可以在模板管理TAB中,选择添加模板,用来创建新的短信模板。创建完成后,会进行审核。

创建成功后的短信模板CODE需要记住,后续会使用到

在短信服务管理平台的概览界面,可以选择AccessKey按钮进行创建集成短信服务所需要的AccessKey和AccessKeySecret。

程序中集成短信服务
client, err := dysmsapi.NewClientWithAccessKey(smsConfig.RegionId, smsConfig.AppKey, smsConfig.AppSecret)
if err != nil {
toolbox.Error(err.Error())
return ""
} request := dysmsapi.CreateSendSmsRequest()
request.Scheme = "https" request.SignName = smsConfig.SignName
request.TemplateCode = smsConfig.TemplateCode
request.PhoneNumbers = phone par, err := json.Marshal(map[string]interface{}{
"code": code,
})
request.TemplateParam = string(par) response, err := client.SendSms(request) fmt.Println( response)
if err != nil {
toolbox.Error(err.Error())
return ""
}

我们通过上述核心代码程序,完成阿里云短信服务的集成。其中:

  • SignName:在阿里云后台创建的前名,必传参数。
  • TemplateCode:在阿里云后台创建的短信模板ID,必传参数。
  • PhoneNumbers:接收短信的手机号码,必传参数。

创建阿里云短信服务sdk的client时,需要传regionID、appKey、accessKeySecret三个参数。regionID表示的是区域ID,可以填写cn-hangzhou。

创建Controller解析请求

无论是短信登录,还是用户名和密码登录,均属于用户功能模块。因此,创建MemberController用于解析用户模块的各个请求:

package controller

import (
"CloudRestaurant/service"
"fmt"
"github.com/gin-gonic/gin"
) type MemberController struct {} func (mc *MemberController) Router(engine *gin.Engine) {
engine.GET("/api/sendcode",mc.sendSmsCode)
} // http://localhost:8090/api/sendcode?phone=18621048481
func (mc *MemberController) sendSmsCode(c *gin.Context) {
// 发送验证码
phone,exist := c.GetQuery("phone")
fmt.Println(phone,"phone --->")
if !exist {
c.JSON(200,map[string]interface{}{
"code":0,
"msg":"参数解析失败",
})
return
}
ms := service.MemberService{}
isSend := ms.Sendcode(phone)
if isSend {
c.JSON(200,map[string]interface{}{
"code":1,
"msg":"发送成功",
})
return
} c.JSON(200,map[string]interface{}{
"code":0,
"msg":"发送失败",
})
}

创建用户控制层程序MemberController,使用GET方法解析客户端发送短信验证码的请求,请求接口为:/api/sendcode,同时指定sendSmsCode方法处理接口请求。

在实际的开发中,程序功能往往是分层来进行开发的,controller层只负责控制和处理接口请求的逻辑,具体的功能调用,往往由另外称为service层的功能服务层来进行实现。

创建service层

在service层中,依然按照模块化开发的理念,将用户模块的服务统一由UserServicej进行提供。因此,创建MemberService,并提供SendCode方法。

package service

import (
"CloudRestaurant/tool"
"encoding/json"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
"github.com/wonderivan/logger"
"math/rand"
"time"
) type MemberService struct { } func (ms *MemberService) Sendcode(phone string) bool {
// 1.产生一个验证码
code := fmt.Sprintf("%06v",rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(1000000)) // 2.调用阿里云服务
config := tool.GetConfig().Sms
client, err := dysmsapi.NewClientWithAccessKey(config.RegionId, config.AppKey, config.AppSecret)
if err != nil {
logger.Error(err.Error())
return false
} request := dysmsapi.CreateSendSmsRequest()
request.Scheme = "https"
request.SignName = config.SignName
request.TemplateCode = config.TemplateCode
request.PhoneNumbers = phone par,err := json.Marshal(map[string]interface{}{
"code":code,
})
request.TemplateParam = string(par) response,err :=client.SendSms(request)
fmt.Println(response,"response --->")
if err != nil {
logger.Error(err.Error())
return false
} // 3. 接受返回结果,并判断发送状态
if response.Code == "OK" {
return true
}
return false
}

测试

在postman中, 使用/api/sendcode接口进行测试,详细url如下:

http://localhost:8090/api/sendcode?phone=13167582436

然后就能在手机端收到验证码

创建数据库和数据表

上面已经接入了第三方的短信服务SDK功能,可以接受短信验证码。在用户接受到验证码以后,输入验证码进行登录,我们需要验证用户输入的验证码是否正确。

因此,我们需要将发送过的验证码通过持久化的方式保存下来,方便我们进行校验。

我们选择通过数据库来存储用户手机验证码。

xorm介绍及安装

在项目开发过程中,我们会使用一些成熟的框架来操作数据库。xorm就是一个比较流行的数据库操作orm框架。

安装xorm

go get github.com/go-xorm/xorm

安装Mysql驱动

go get github.com/go-sql-driver/mysql
连接数据库

在连接数据库之前,首先要创建数据库。在mysql中创建cloudrestaurant数据库:

create database cloudrestaurant;

创建完数据库并安装好xorm库以后,使用xorm进行连接数据库

import (
"github.com/go-xorm/xorm"
_ "github.com/go-sql-driver/mysql"
)
database := cfg.Database
conn := database.User + ":" + database.Password + "@tcp(" + database.Host + ":" + database.Port + ")/" + database.DbName + "?charset=" + database.Charset
engine, err := xorm.NewEngine(database.Driver, conn)
if err != nil {
return nil, err
}

连接数据库有些参数需要自己指定,比如说驱动类型,登录数据库的用户名,密码,数据库名等。将这些变量配置在app.json配置文件中,如下所示:

{
"database": {
"driver": "mysql",
"user": "root",
"password": "12345678",
"host": "127.0.0.1",
"port": "3306",
"db_name": "cloudrestaurant",
"charset": "utf8mb4",
"show_sql": true
}
}

在Config结构体中添加对database的解析

type Config struct {
AppName string `json:"app_name"`
AppMode string `json:"app_mode"`
AppHost string `json:"app_host"`
AppPort string `json:"app_port"`
Database DatabaseConfig `json:"database"`
Sms SmsConfig `json:"sms"`
}
type DatabaseConfig struct {
Driver string `json:"driver"`
User string `json:"user"`
Password string `json:"password"`
Host string `json:"host"`
Port string `json:"port"`
DbName string `json:"db_name"`
Charset string `json:"charset"`
ShowSql bool `json:"show_sql"`
}
创建SmsCode

要存储验证码,需要在数据库中创建表结构进行存储。我们可以创建SmsCode结构体,并通过tag设置数据库字段约束,具体的SmsCode定义如下:

package model

type SmsCode struct {
Id int64 `xorm:"pk autoincr" json:"id"`
Phone string `xorm:"varchar(11)" json:"phone"`
BizId string `xorm:"varchar(30)" json:"biz_id"`
Code string `xorm:"varchar(4)" json:"code"`
CreateTime int64 `xorm:"bigint" json:"create_time"`
}

通过tag的xorm设置字段数据类型以及约束。

  • pk:表示主键
  • autoinc:表示自增
  • bigint:整形变量
  • varchar:字符串类型
Sync2同步生成数据库表

可以调用engine.Sync2方法,将结构体类型同步映射到数据库中,生成数据库表。

err = engine.Sync2(new(model.SmsCode))
if err != nil {
return nil, err
}
将验证码数据保存到数据库

在MemberService的SendCode方法,添加保存验证码到数据库的操作:

func (msi *MemberServiceImpl) SendCode(phone string) string {
code := fmt.Sprintf("%06v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(1000000))
...
dao := impl.NewMemberDao()
smsCode := model.SmsCode{Phone: phone, Code: code, BizId: response.BizId, CreateTime: time.Now().Unix()} if result := dao.InsertCode(smsCode); result > 0 {
return code
}
return ""
}

02 . 02 . Go之Gin+Vue开发一个线上外卖应用(集成第三方发送短信和xorm生成存储数据库表)的更多相关文章

  1. 01 . Go之Gin+Vue开发一个线上外卖应用

    项目介绍 我们将开始使用Gin框架开发一个api项目,我们起名为:云餐厅.如同饿了么,美团外卖等生活服务类应用一样,云餐厅是一个线上的外卖应用,应用的用户可以在线浏览商家,商品并下单. 该项目分为客户 ...

  2. 03 . Gin+Vue开发一个线上外卖应用(用户数据创建,插入,跨域处理)

    功能和背景介绍 在项目的登录功能中,如果在登录时发现用户名和密码在用户表中不存在,会自动将用户名和密码保存在用户表中,创建一个新的用户. 因此,除了使用手机号和验证码登录以外,还支持使用用户名.密码进 ...

  3. 04 . Go+Vue开发一个线上外卖应用(用户名密码和图形验证码)

    图形化验证码生成和验证 功能介绍 在使用用户名和密码登录功能时,需要填写验证码,验证码是以图形化的方式进行获取和展示的. 验证码使用原理 验证码的使用流程和原理为:在服务器端负责生成图形化验证码,并以 ...

  4. 05 . Go+Vue开发一个线上外卖应用(Session集成及修改用户头像到Fastdfs)

    用户头像上传 功能介绍 在用户中心中,允许用户更换自己的头像.因此,我们开发上传一张图片到服务器,并保存成为用户的头像. 接口解析 在用户模块的控制器MemberController中,解析头像上传的 ...

  5. JavaWeb-SpringBoot_一个类实现腾讯云SDK发送短信

    腾讯云应用列表 传送门 使用Gradle编译项目 传送门 SDK&API:qcloudsms_java 传送门 package com.Gary.sms.controller; import ...

  6. 用Vue开发一个实时性时间转换功能,看这篇文章就够了

    前言 最近有一个说法,如果你看见某个网站的某个功能,你就大概能猜出背后的业务逻辑是怎么样的,以及你能动手开发一个一毛一样的功能,那么你的前端技能算是进阶中高级水平了.比如咱们今天要聊的这个话题:如何用 ...

  7. 用vue开发一个app(4,一个久等了的文章)H5直播平台登录注册(1)

    我上一篇关于vue的文章和这一篇时间隔了有点久了.最近终于写完了. 因为我一直想写个有点实绩的东西,而不是随便写一个教程一样东西.结合最近在项目中学到的经验和我的一点创意. 首先介绍下这是个什么! H ...

  8. 2440开发板linux系统移植3G拨号上网收发短信(三)

    一.用text查看模式 下面的“发”是指我敲的命令,“收”是指回车后显示的信息包括其他接收的信息. ~ >: microcom -s 115200 /dev/ttyUSB1 发:at 收:OK ...

  9. 用qpython3写一个最简单的发送短信的程序

    到目前为止并没有多少手机应用是用python开发的,不过qpython可以作为一个不错的玩具推荐给大家来玩. 写一个最简单的发送短信的程序,代码如下: #-*-coding:utf8;-*- #qpy ...

随机推荐

  1. 最新版PyCharm激活教程!有效期至2089年!

    Python的编译器有很多,像Pycharm.VsCode.Jupyter...哪个好用不做评价,各有各的优点!用过PyCharm的同学都知道,PyCharm有两大版本,专业版和社区版,专业版相当于社 ...

  2. Kafka监控必备——Kafka-Eagle 2.0.2正式发布

    对于经常使用Kafka的同学,拥有一个炫酷又实用的监控系统是非常有必要的.可以实时的监控数据流的情况,了解实时数据流的变化. Kafka Eagle Kafka Eagle是一个监控系统,监控Kafk ...

  3. Centos-删除文件或目录-rm

    rm 删除目录或者文件,如果是链接文件,则只删除这个链接文件而不是链接指向的文件 相关选项 -r 递归删除目录 -f 忽略不存在提示和确认提示,本身确认提示系统默认添加-i参数 -i 删除文件前提示, ...

  4. Pyinstaller打包通用流程

    Pyinstaller打包通用流程 前言 什么是Pyinstaller Pyinstaller是用于打包python项目的一个工具, 可以将项目代码打包成可执行文件, 在其他机器上使用. 通俗的说, ...

  5. 062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用

    062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用 本文知识点:二维数组应用 二维数组的声明和创建 ? 出现空指针异常 数组的名字指向数组的第 ...

  6. aptitude命令

    命令 作用 aptitude update 更新可用的包列表 aptitude upgrade 升级可用的包 aptitude dist-upgrade 将系统升级到新的发行版 aptitude in ...

  7. angularCroppie

    下载 angularCroppieangularCroppie 图像Cropper使用Croppie 安装 Npm: Npm安装角croppie 使用 添加依赖项:angular.模块("m ...

  8. redis协议规范

    好多年前看过redis的代码,那个时候还是2.6的版本,集群和哨兵还没加入正式代码,这几年redis发展的好快.简略翻译一篇文章redis的https://redis.io/topics/protoc ...

  9. 99%的Android开发不得不面对的三道坎,到底该怎么破?

    今年比往年要特殊一些,受疫情的影响,很多公司都出现了裁员现象.以至于最近很多技术同学也在纷纷向我倒苦水. 王鹏便是其中的一员,王鹏之前是在一线城市的一家小型互联网公司做Android应用开发.从毕业实 ...

  10. 例题3-3 回文词(Palindromes, UVa401)

    输入一个字符串,判断它是否为回文串以及镜像串.输入字符串保证不含数字0.所谓 回文串,就是反转以后和原串相同,如abba和madam.所有镜像串,就是左右镜像之后和原串相同,如2S和3AIAE.注意, ...