golang后端接入MOB的短信服务

2023-11-27 03:00

本文主要是介绍golang后端接入MOB的短信服务,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景:

初学golang,想和同学前后端分离做个小APP,我负责后端。
需要用到短信服务来做验证码登陆,选择了MobTech的SMS服务(一个月免费1W条,MOB牛逼!)

问题:

以前做的短信登陆逻辑如图:
在这里插入图片描述
MOB文档中给出了两种策略:
在这里插入图片描述
在这里插入图片描述
我感觉第一种后端不涉及验证过程的策略可能存在安全隐患,因为校验短信验证码的动作发生在前端,之后由开发者在前端回调后台的业务接口诸如登陆和注册。
那么在调用这一业务接口时,肯定需要前端引入某种加密策略,来确保对该接口的请求一定是前端经过完整的验证码流程后发起的,只有这样才能保证用户身份的正确。
在这种情况下,如果前端的加密策略泄露,可能导致不法分子伪装其他用户的身份进行登陆或其他权限相关操作,就糟糕了。

以上仅是我这个初学者结合以往经验的一点点猜测,既然这种模式存在于官方文档中,那肯定有足够安全的实现策略,不过我现在还不知道: (

我暂时就先用自己理解上觉得更安全、更顺手的第二种策略来实现。

在此先附上MobTech的SMS服务接入文档:
Mob文档中心 / SMSSDK

注册账号并创建应用、企业认证过程这里就不提了。
前端根据不同实现可以参考上述文档快速接入SDK。
后端如果要采用第二种策略,需要进行以下操作:

  1. 填入部署后端应用的服务器的ip
    在这里插入图片描述
  2. 对Mob提供的验证码校验接口进行封装
package smsimport ("encoding/json""errors""fmt""io/ioutil""net/http""net/url""strings"
)//短信服务功能封装//默认区号为中国(+86)
const DEFAULT_ZONE = "86"//MOB提供的验证码校验接口
const VERIFY_URL = "https://webapi.sms.mob.com/sms/verify"const APP_KEY = "xxxxxxxx"
const APP_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxxxx"//校验收到的验证码
func VerifyCode(phone, code string) (bool, error) {//********************************************************//* 通过json的方式进行post请求的传参  在这里是不适用的!!!    *//********************************************************//contentType := "application/json"//data := mapToJSON(&map[string]interface{}{//	"phone":  phone,//	"code":   code,//	"appkey": "31db8a6381fb0",//	"zone":   DEFAULT_ZONE,//})//resp, err := http.Post(VERIFY_URL, contentType, strings.NewReader(data))urlValues := url.Values{"phone":  {phone},"code":   {code},"appkey": {APP_KEY},"zone":   {DEFAULT_ZONE},}reqBody:= urlValues.Encode()resp, err := http.Post(VERIFY_URL, "text/html",strings.NewReader(reqBody))if err != nil {fmt.Printf("post failed, err:%v\n", err)return false, err}defer resp.Body.Close()b, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Printf("get resp failed, err:%v\n", err)return false, err}//json序列化成map 解析MOB验证接口的返回值var tempMap map[string]interface{}err = json.Unmarshal([]byte(b), &tempMap)if err != nil {fmt.Printf("parse resp failed, err:%v\n", err)return false, err}fmt.Println("接口返回的状态码是:",tempMap["status"])fmt.Println("接口返回的message是:",tempMap["error"])//根据接口返回状态码 判断验证码结果switch int(tempMap["status"].(float64)) {case 200:return true, nildefault:return false,errors.New(tempMap["error"].(string))}
}//map转json
func mapToJSON(tempMap *map[string]interface{}) string {data, err := json.Marshal(tempMap)if err != nil {panic(err)}return string(data)
}

注意,这里有一个坑!
在golang里,post请求传参有三种常见的方式:

  • conten-type : text/html 这种实际上是把参数拼接到url上)

  • conten-type : application/x-www-form-urlencoded

  • conten-type : application/json

    对应到golang代码中有以下三种写法:

  •  	  urlValues := url.Values{"name":{"zhaofan"},"age":{"23"},}reqBody:= urlValues.Encode()resp, _ := http.Post("http://xxxxxx", "text/html",strings.NewReader(reqBody))body,_:= ioutil.ReadAll(resp.Body)fmt.Println(string(body))
    
  •      urlValues := url.Values{}urlValues.Add("name","zhaofan")urlValues.Add("age","22")resp, _ := http.PostForm("http://httpbin.org/post",urlValues)body, _ := ioutil.ReadAll(resp.Body)fmt.Println(string(body))
    
  •  	 data := mapToJSON(&map[string]interface{}{"phone":  phone,"code":   code,"appkey": "31db8a6381fb0","zone":   DEFAULT_ZONE,})resp, _:= http.Post(VERIFY_URL, contentType, strings.NewReader(data))body, _ := ioutil.ReadAll(resp.Body)fmt.Println(string(body))//map转jsonfunc mapToJSON(tempMap *map[string]interface{}) string {data, err := json.Marshal(tempMap)if err != nil {panic(err)}return string(data)}
    

当我使用第三种JSON传参的时候,MOB的验证接口一直给我报405 AppKey为空
改用第一种、第二种传参方式之后都能够正常调用。
估计是mob提供的这个接口在解析参数时不支持json传参。

这也体现出了gin框架在http请求参数解析时的强大之处:
只需要在声明接收参数的结构体时,给对应字段添加几个“注解”
(暂时不知道这个小引号的学名,先这么叫它^^)
再结合func (c *Context) ShouldBind(obj interface{}) error就能完美实现httpRequest的参数获取。

//接受参数的实体
type Verify struct {Phone    string     `form:"phone" json:"phone" binding:"required"`Code     string 	`form:"code" json:"code" binding:"required"`
}var verify Verify	//用于装载参数的结构体
if err := c.ShouldBind(&verify); err == nil {...}//读取参数后的业务逻辑
  1. 给前端提供校验接口,可以整合自己的登陆或注册等等业务逻辑
//接受参数的实体
type Verify struct {Phone    string `form:"phone" json:"phone" binding:"required"`Code string 	`form:"code" json:"code" binding:"required"`
}
//这是一个功能接口 POST类型 路由为 '/phone' 用于手机或者注册
func phone(c *gin.Context) {//获取请求参数...业务逻辑var verify Verifyif err := c.ShouldBind(&verify); err == nil {fmt.Printf("verify info:%#v\n", verify)//1、校验验证码isCorrect,_ := sms.VerifyCode(verify.Phone,verify.Code)//验证码正确if isCorrect {//2、校验手机号是否存在 不存在则先注册再返回token 存在则直接返回tokenbyPhone, _ := service.GetUserByPhone(verify.Phone)if byPhone==(bean.User{}) {//用户不存在c.JSON(http.StatusOK,response.Ok("新用户注册成功",nil))}else{//用户已存在c.JSON(http.StatusOK,response.Ok("登陆成功",nil))}}else{//验证码不正确c.JSON(http.StatusOK,response.Fail("验证码错误"))}} else {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})}
}



收工!

在这里插入图片描述

这篇关于golang后端接入MOB的短信服务的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/426906

相关文章

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

SysMain服务可以关吗? 解决SysMain服务导致的高CPU使用率问题

《SysMain服务可以关吗?解决SysMain服务导致的高CPU使用率问题》SysMain服务是超级预读取,该服务会记录您打开应用程序的模式,并预先将它们加载到内存中以节省时间,但它可能占用大量... 在使用电脑的过程中,CPU使用率居高不下是许多用户都遇到过的问题,其中名为SysMain的服务往往是罪魁

解决若依微服务框架启动报错的问题

《解决若依微服务框架启动报错的问题》Invalidboundstatement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,... 目录ruoyi-system模块报错报错详情nacos文件目录总结ruoyi-systnGLNYpe

Nginx进行平滑升级的实战指南(不中断服务版本更新)

《Nginx进行平滑升级的实战指南(不中断服务版本更新)》Nginx的平滑升级(也称为热升级)是一种在不停止服务的情况下更新Nginx版本或添加模块的方法,这种升级方式确保了服务的高可用性,避免了因升... 目录一.下载并编译新版Nginx1.下载解压2.编译二.替换可执行文件,并平滑升级1.替换可执行文件

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

全面解析Golang 中的 Gorilla CORS 中间件正确用法

《全面解析Golang中的GorillaCORS中间件正确用法》Golang中使用gorilla/mux路由器配合rs/cors中间件库可以优雅地解决这个问题,然而,很多人刚开始使用时会遇到配... 目录如何让 golang 中的 Gorilla CORS 中间件正确工作一、基础依赖二、错误用法(很多人一开

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,