当前位置: 首页 > 科技观察

Go语言实现发送短信验证码和登录

时间:2023-03-12 03:36:31 科技观察

首先申请短信服务商,如腾讯云、阿里云、网易易盾等,腾讯云可以申请微信公众号,然后申请相关的短信签名,以及短信模板,腾讯有100个试用版。具体代码实现:配置腾讯云短信服务的短信发送相关配置,具体配置请参考腾讯云短信服务的api文档进行配置。sms:secret-key:#secretkey,可以在控制台查询secret-id:#secretkeyid,可以在控制台查询sms-sdk-app-id:#applicationidSign-name:#appliedsignaturetemplate-id:#Templateidgo这里使用viper加载配置。相关加载配置代码如下定义相关配置结构,加载到整个项目的整体options配置结构中。//发送短信的短信配置optionstypeSmsOptionsstruct{SecretKeystring`json:"secret-key,omitempty"mapstructure:"secret-key"`SecretIdstring`json:"secret-id,omitempty"mapstructure:"secret-id"`SmsSdkAppId字符串`json:"sms-sdk-app-id,omitempty"mapstructure:"sms-sdk-app-id"`SignName字符串`json:"sign-name,omitempty"mapstructure:"sign-name"`TemplateId字符串`json:"template-id,omitempty"mapstructure:"template-id"`}funcNewSmsOptions()*SmsOptions{return&SmsOptions{SecretKey:"",SecretId:"",SmsSdkAppId:"",SignName:"",TemplateId:"",}}//这是项目的选项配置。项目启动时,会加载yaml到optionstypeOptionsstruct{GenericServerRunOptions*genericoptions.ServerRunOptions`json:"server"mapstructure:"server"`MySQLOptions*genericoptions.MySQLOptions`json:"mysql"mapstructure:"mysql"`InsecuresServing*genericoptions.InsecureServerOptions`json:"insecure"mapstructure:"insecure"`Log*logger.Options`json:"log"mapstructure:"log"`RedisOptions*genericoptions.RedisOptions`json:“redis”映射结构:“redis”`SmsOptions*genericoptions.SmsOptions`json:“sms”映射结构:“sms”`}funcNewOptions()*Options{o:=Options{GenericServerRunOptions:genericoptions.NewServerRunOptions(),MySQLOptions:genericoptions.NewMySQLOptions(),InsecuresServing:genericoptions.NewInsecureServerOptions(),RedisOptions:genericoptions.NewRedisOptions(),Log:logger.NewOptions(),SmsOptions:genericoptions.NewSmsOptions(),}return&o}viper加载配置的代码如下:funcAddConfigToOptions(options*options.Options)错误{viper.SetConfigName("config")viper.AddConfigPath("config/")viper.SetConfigType("yaml")err:=viper.ReadInConfig()iferr!=nil{returnerr}optDecode:=viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(mapstructure.StringToTimeDurationHookFunc(),StringToByteSizeHookFunc()))err=viper.Unmarshal(options,optDecode)fmt.Println(options)iferr!=nil{returnerr}returnnil}funcStringToByteSizeHookFunc()mapstructure.DecodeHookFunc{returnfunc(f反射.Type,treflect.Type,datainterface{})(interface{},error){iff.Kind()!=reflect.String{returndata,nil}ift!=reflect.TypeOf(datasize.ByteSize(5)){returndata,nil}raw:=data.(string)result:=new(datasize.ByteSize)result.UnmarshalText([]byte(raw))returnresult.Bytes(),nil}}下面是发送验证码的实际发现:typeSmsClientstruct{Credential*common.CredentialRegionstringCpf*profile.ClientProfileRequestSmsRequest}typeOptionfunc(*SmsClient)funcNewSmsClient(options...func(client*SmsClient))*SmsClient{client:=&SmsClient{region:"ap-guangzhou",Cpf:profile.NewClientProfile(),}for_,option:=rangeoptions{option(client)}returnclient}funcWithRequest(requestSmsRequest)选项{returnfunc(smsClient*SmsC客户端){smsClient.Request=请求}}funcWithCredential(选项options.SmsOptions)选项{returnfunc(smsClient*SmsClient){smsClient.Credential=common.NewCredential(options.SecretId,options.SecretKey)}}funcWithCpfReqMethod(字符串)选项{returnfunc(smsClient*SmsClient){smsClient.Cpf.HttpProfile.ReqMethod=方法}}funcWithCpfReqTimeout(timeoutint)(方法字符串)选项{returnfunc(smsClient*SmsClient){smsClient.Cpf.SignMethod=method}}func(s*SmsClient)Send()bool{sendClient,_:=sms.NewClient(s.Credential,s.Region,s.Cpf)_,err:=sendClient.SendSms(s.Request.request)if_,ok:=err.(*errors.TencentCloudSDKError);ok{logger.Warnf("API错误已返回:%s",err)returnfalse}iferr!=nil{logger.Warnf("发送短信失败:%s,requestId:%s",err)returnfalse}logger.Info("发送短信验证码成功")returntrue}定义客户端发送,这里使用function选项编程模式来初始化发送客户端。发送请求,请求代码如下:NewSendSmsRequest()request.SmsSdkAppId=&options.SmsSdkAppIdrequest.SignName=&options.SignNamerequest.TemplateId=&options.TemplateIdsmsRequest:=&SmsRequest{request:request}for_,option:=rangewithOptions{smsRequest)}returnsmsRequest}typeRequestOption函数(*SmsRequest)funcWithPhoneNumberSet(phoneSet[]string)RequestOption{返回func(smsRequest*SmsRequest){smsRequest.request.PhoneNumberSet=common.StringPtrs(phoneSet)}}funcWith(SettemplateParamSet]string)RequestOption{returnfunc(smsRequest*SmsRequest){smsRequest.request.TemplateParamSet=common.StringPtrs(templateSet)}}创建发送验证码的控制层,发送成功,将这里的电话号码和验证码保存到redis缓存中,就是我们ed用于在登录时验证验证码的有效性func(u*userService)SendPhoneCode(ctxcontext.Context,phonestring)bool{//获取配置参数smsSetting:=global.TencenSmsSettingphoneSet:=[]string{phone}//随机生成6位验证码varrandCodestring=fmt.Sprintf("%06v",rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(1000000))templateSet:=[]string{randCode,"60"}smsRequest:=tencenSms.NewSmsRequest(smsSetting,tencenSms.WithPhoneNumberSet(phoneSet),tencenSms.WithTemplateParamSet(templateSet))smsClient:=tencenSms.NewSmsClient(tencenSms.WithRequest(*smsRequest),tencenSms.WithCredential(*smsSetting.)go发送(客户端)//将验证码和手机号保存在redis_=u.cache.UserCaches().SetSendPhoneCodeCache(ctx,phone,randCode)returntrue}接着是通过手机验证码登录的过程:func(u*userService)LoginByPhoneCode(ctxcontext.Context,phonestring,phoneCod