go 实现发送短信验证码登录
生活随笔
收集整理的這篇文章主要介紹了
go 实现发送短信验证码登录
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
現在大多數app或wap都實現了通過手機號獲取驗證碼進行驗證登錄,下面來看下用go來實現手機號發送短信驗證碼登錄的過程,基于的框架是gin 。
- 首先是短信服務商的申請,比如騰訊云、阿里云、網易易盾等,騰訊云自己申請個微信公眾號就行,然后申請相關的短信簽名、和短信模板,騰訊有100條試用喔。
- 具體的代碼實現
- 配置騰訊云短信服務的發送短信相關配置,具體可以參考騰訊云短信服務的api 文檔,進行配置
go 這里采用的是viper進行加載配置,相關的加載配置代碼如下
定義相關的配置結構體,并加載到整個項目的總的options 配置結構體中
viper加載配置的代碼如下
func AddConfigToOptions(options *options.Options) error {viper.SetConfigName("config")viper.AddConfigPath("config/")viper.SetConfigType("yaml")err := viper.ReadInConfig()if err != nil {return err}optDecode := viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(mapstructure.StringToTimeDurationHookFunc(), StringToByteSizeHookFunc()))err = viper.Unmarshal(options, optDecode)fmt.Println(options)if err != nil {return err}return nil }func StringToByteSizeHookFunc() mapstructure.DecodeHookFunc {return func(f reflect.Type,t reflect.Type, data interface{}) (interface{}, error) {if f.Kind() != reflect.String {return data, nil}if t != reflect.TypeOf(datasize.ByteSize(5)) {return data, nil}raw := data.(string)result := new(datasize.ByteSize)result.UnmarshalText([]byte(raw))return result.Bytes(), nil} }下面是發送驗證碼的實現
type SmsClient struct {Credential *common.CredentialRegion stringCpf *profile.ClientProfileRequest SmsRequest }type Option func(*SmsClient)func NewSmsClient(options ...func(client *SmsClient)) *SmsClient {client := &SmsClient{Region: "ap-guangzhou",Cpf: profile.NewClientProfile(),}for _, option := range options {option(client)}return client}func WithRequest(request SmsRequest) Option {return func(smsClient *SmsClient) {smsClient.Request = request} }func WithCredential(options options.SmsOptions) Option {return func(smsClient *SmsClient) {smsClient.Credential = common.NewCredential(options.SecretId, options.SecretKey)} } func WithCpfReqMethod(method string) Option {return func(smsClient *SmsClient) {smsClient.Cpf.HttpProfile.ReqMethod = method} } func WithCpfReqTimeout(timeout int) Option {return func(smsClient *SmsClient) {smsClient.Cpf.HttpProfile.ReqTimeout = timeout} } func WithCpfSignMethod(method string) Option {return func(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("An API error has returned: %s", err)return false}if err != nil {logger.Warnf("發送短信失敗:%s,requestId:%s", err)return false}logger.Info("發送短信驗證碼成功")return true }定義發送的client,這里采用function option 的編程模式來初始化發送的client.和發送的request,request的代碼如下
type SmsRequest struct {request *sms.SendSmsRequest }func NewSmsRequest(options *options.SmsOptions, withOptions ...func(smsRequest *SmsRequest)) *SmsRequest {request := sms.NewSendSmsRequest()request.SmsSdkAppId = &options.SmsSdkAppIdrequest.SignName = &options.SignNamerequest.TemplateId = &options.TemplateIdsmsRequest := &SmsRequest{request: request}for _, option := range withOptions {option(smsRequest)}return smsRequest}type RequestOption func(*SmsRequest)func WithPhoneNumberSet(phoneSet []string) RequestOption {return func(smsRequest *SmsRequest) {smsRequest.request.PhoneNumberSet = common.StringPtrs(phoneSet)} }func WithTemplateParamSet(templateSet []string) RequestOption {return func(smsRequest *SmsRequest) {smsRequest.request.TemplateParamSet = common.StringPtrs(templateSet)} }創建發送驗證碼的控制層,發送成功,并將此處的電話號碼和驗證碼保存到redis緩存中,用來登錄時候的驗證碼有效性的校驗。
func (u *userService) SendPhoneCode(ctx context.Context, phone string) bool {// 獲取配置參數smsSetting := global.TencenSmsSettingphoneSet := []string{phone}// 隨機生成6位的驗證碼var randCode string = 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 smsClient.Send()// 將驗證碼和手機號保存到redis中_ = u.cache.UserCaches().SetSendPhoneCodeCache(ctx, phone, randCode)return true}后面是通過手機驗證碼進行登錄的流程
func (u *userService) LoginByPhoneCode(ctx context.Context, phone string, phoneCode string) (*model.User,error) {// 從緩存中獲取該手機號對應的驗證碼是否匹配cacheCode, err :=u.cache.UserCaches().GetSendPhoneCodeFromCache(ctx,phone)if err != nil {return nil, errors.WithCode(code.ErrUserPhoneCodeExpire,err.Error())}if cacheCode!=phoneCode {return nil,errors.WithCode(code.ErrUserPhoneCodeMiss,"")}return &model.User{Nickname: "lala",}, nil}總結
以上是生活随笔為你收集整理的go 实现发送短信验证码登录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32L051测试 (一、使用Cub
- 下一篇: 基于SVPWM的三相全桥逆变器,输出电压