【后端学习笔记·Golang】邮箱登陆验证

文章目录

  • 邮箱登陆验证
    • 生成随机验证码
    • 向用户邮箱发送验证码
    • 接口
      • 获取验证码
      • 校验验证码

邮箱登陆验证

流程:

  • 接收用户请求后生成随机验证码,并将验证码存入Redis中,并设置TTL

  • 通过gomail发送验证码给用户邮箱

  • 接收用户输入的验证码,与Redis中存放的验证码进行比对

生成随机验证码

​ 随机种子通过 time.Now().UnixNano() 进行设置,以确保对于同一个用户每次请求都使用不同的种子。然后,定义了一个包含数字字符的 letters 切片。每次通过 rand.Intn(len(letters)) 随机选择 letters 切片中的一个字符,并将其存储在 b 中。最后,将 b 转换为字符串并返回。

import (
	"math/rand"
	"time"
)
func GenerateRandomCode(length int) string {
	rand.Seed(time.Now().UnixNano())
	var letters = []rune("0123456789")
	b := make([]rune, length)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)
}

向用户邮箱发送验证码

  • 这里使用了gomail进行发送邮箱验证码。gomail package - gopkg.in/gomail.v2 - Go Packages
  • 此处密码为授权码而非登陆密码,以qq为例:需要在邮箱设置->账号安全->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务处开启服务,然后获取授权码
  • Host:SMTP 服务器的主机地址。
  • Port:SMTP 服务器的端口号。
  • Username:SMTP 服务器的邮箱账号。
  • Password:SMTP 服务器的密码。
# qq邮箱
host: smtp.qq.com
port: 587
username: ********@qq.com
password: ********
// 发送邮箱验证码
func EmailSendCode(ctx context.Context, email string) (code string, err error) {
	// 生成6位随机验证码
	code = vcode.GenerateRandomCode(6)
	m := gomail.NewMessage()
	m.SetHeader("From", cfg.username)
	m.SetHeader("To", email)
	m.SetHeader("Subject", "验证码")
	msg := fmt.Sprintf("您的验证码为: %s", code)
	m.SetBody("text/html", msg)
	d := gomail.NewDialer(cfg.host, cfg.port, cfg.username, cfg.password)
	err = d.DialAndSend(m)
	return
}

接口

Goframe 框架

获取验证码

​ 如果发送验证码成功,将验证码存储到 Redis 中。这里 使用SETEX 命令设置了一个键值对,键以邮箱地址为后缀,值是验证码,过期时间设置为 120 秒(2 分钟)。(Goframe框架)

func (c *ControllerV1) SendCode(ctx context.Context, req *v1.SendCodeReq) (res *v1.SendCodeRes, err error) {
	res = &v1.SendCodeRes{}
	code, err := email.EmailSendCode(ctx, req.Email)
	if err != nil {
		return
	}
    // 将验证码存入Redis中,并设置TTL
	_, err = g.Redis().Do(ctx, "SETEX", fmt.Sprintf("code.%s", req.Email), 120, code)
	if err != nil {
		return
	}
	res.States = true
	return
}

校验验证码

​ 检查请求中是否包含验证码。如果验证码非空,则从 Redis 中获取之前发送给该邮箱的验证码,并与请求中的验证码进行比较。如果验证码不匹配,则返回一个错误。验证码正确则查询用户信息,用用户的唯一标识符获取 JWT 令牌。最后,将 JWT 令牌包装在响应对象中返回。

func (c *ControllerV1) Login(ctx context.Context, req *v1.LoginReq) (res *v1.LoginRes, err error) {
	user := entity.User{
		Email:    req.Email,
	}
	if req.VerificationCode != "" {
		search, _ := g.Redis().Do(ctx, "GET", fmt.Sprintf("code.%s", req.Email))
		code := search.String()
		if code != req.VerificationCode {
			return res, gerror.New("验证码错误或未发送")
		}
	}
    // 查询用户信息
	search, err := service.User().UserInfo(ctx,user)
    if err != nil {
		return
    }
	// 保存jwt令牌
	token, _ := service.JwtStorage().GetJwtAndSave(ctx, search.Id)
	res = &v1.LoginRes{
		Token: token,
	}
	return
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/574392.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面试:JVM垃圾回收

一、三种垃圾回收算法 1、标记清除(已废弃) 找到根对象(局部变量正在引用的对象、静态变量正在引用的对象);沿着根对象的引用链,查看当前的对象是否被根对象所引用,若被引用,则加上…

redis和mysql数据一致性方案

请求 A 更新数据 请求B读数据 在高并发情况下,A、B请求过程步骤相互穿插,就会出现图中的问题。 期望redis 的数据是11,最后变成了10 场景:先删除Redis,再更新 MySQL,不主动更新Redis,访问redi…

软件企业质量保证的基石――QA,QC的良性协作

软件企业质量保证的基石――QA、QC的良性协作 国内的软件产业发展了20多年的时间,已经由个人英雄时代步入到中、小团队协作时代。相信不久的将来,国内一定会出现航母级的软件企业,那时候我们会迎来集团军作战的时代。不同的时代表明软件规模…

【AI相关】数学和统计学知识

数学和统计学的知识可以分为两部分: 一部分是线性代数中的基础概念,比如标量、向量和张量。 另一部分是概率统计中常见的分布类型,比如正态分布和伯努利分布。 线性代数 什么是标量? 标量是一个单独的数,可以是整…

PLC基本原理及其接线

目录: 一、PLC的简介与起源 二、PLC的基本结构 1、MCU模块 2、输入与输出模块 3、电源模块 4、编程设备 三、PLC的外部接线 1、PNP与NPN接线 2、三菱PLC的NPN与PNP设置 下续:三菱FX系列PLC-编程1 一、PLC的简介与起源 1、PLC简介 PLC的全称为…

Prompt之美:如何设计提示词让大模型变“聪明”

目录 一. Prompt关键要素 二. Prompt技巧 三. 实战中的Prompt优化 四. 参考文献 一. Prompt关键要素 Prompt是一个简短的文本输入,用于引导AI模型生成特定的回答或执行特定任务。换句话说,Prompt是你与AI模型沟通的方式。一个好的Prompt可以让AI更准…

猫头虎分享已解决Bug || **Error: ‘Promise‘ is undefined**

博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …

【SpringBoot】00 Maven配置及创建项目

一、Maven配置 1、下载Maven 进入官网下载:Maven – Welcome to Apache MavenMaven – Download Apache Maven 本文以最新版为例,可按需选择版本 Maven – Welcome to Apache Maven 2、解压下载好的安装包 将安装包解压到自己设置的空文件夹中 3、…

抽象的代理模式1.0版本

前言: 在阅读Spring Security官方文档时,里面设计到了一种设计模式——代理模式Proxy 众里寻她千百度,蓦然回首,那人却在灯火阑珊处 开始 在之前的文章里陈述了一个观点——编程语言和语言没有区别 现看看我们日常生活中的代理…

利用 easycode 自动生成 数据库表 对应 类文件

1、安装easycode 打开settings,在plugins中搜索easycode进行安装,安装完成后重启idea。 2、连接数据库 连接数据库,填写数据库配置信息 点解Test connetction测试连接, 3、生成文件 右键数据库表格,生成对应文件 4…

说方法不如传授经验向媒体投稿你可以这样

在信息爆炸的时代,作为单位的信息宣传员,肩负着将本单位的重要资讯、活动成果、政策解读等内容有效传播至公众视野的重任。其中,向各类媒体投稿无疑是实现这一目标的重要途径。然而,传统的邮件投稿方式常常让我深感力不从心,费时费力不说,成功率低、出稿慢等问题更是让我和领导…

商标申请注册交费就一定会下注册证?

近日遇到一个网友说普推知产老杨说,他以为商标交钱就一定会下商标注册证,这个不管找哪家也做不到的。商标申请注册时要给商标局交费用,交完费用商标才有商标的形式审查,通过后下受理书,才有后面商标实质审查&#xff0…

[柏鹭杯 2021]试试大数据分解?

题目:(NSSCTF | 在线CTF平台) 题目就是如此,我没看到有5个不同的文本,其中最后一个文本以pem后缀,所以我们先来了解一下什么是pem格式。 PEM 格式 PEM格式通常用于数字证书认证机构(Certifica…

UI自动化测试框架:PO 模式+数据驱动(超详细)

🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号【互联网杂货铺】,回复 1 ,免费获取软件测试全套资料,资料在手,涨薪更快 1、PO 设计模式简介 什么是 PO 模式? PO&#xff…

雅特力AT32F435学习——2.ADC实验

ADC实验 ADC是什么、重要性就不再这里多说,ADC这个外设以及关于ADC的应用程序用途非常之广泛很值得深挖,接下来就让我们学一下雅特力AT32F435单片机的ADC吧。 基础知识 不同厂商的单片机的ADC外设都是有区别的,比如ADC转换位数、采样频率等…

【SpringCloud】OpenFeign高级特性

【SpringCloud】OpenFeign高级特性 文章目录 【SpringCloud】OpenFeign高级特性1. 超时控制1.1 全局配置1.2 指定配置 2. 重试机制3. 替换Http客户端3.1 引入依赖3.2 配置 4. 请求/响应压缩5. 日志打印6. 综合配置 1. 超时控制 默认OpenFeign客户端等待60秒钟,但是服…

传承汉字,发扬光大!让《米小圈动画汉字》也出一份力吧!

目前社会上出现的诸如“计算机是汉字的掘慕人”、“汉字是行将就木的老人”“必须废除汉字,汉字要走拼音化迷路”等观点,值得重视。专家们说,20年前如提汉字要走拼音化道路,主要是缘于汉字难以输入电脑,而时至今日,汉字在电脑上早已畅通无阻,如果仍坚持“汉字拙劣,必得用拼音文…

SAP 如何控制生产订单发料后不能删除组件

SAP默认的情况下,即使工单中的组件已发料了,但仍可以进行删除的标志。这种情况是不太符合逻辑的,如果真要删除,应该先退料,然后再上删除标志。并不能再物料还是已领料的状态下 就对物料做删除的操作。 如下图 生产订单在已经领料的情况下,仍然的被打上了删除标识。 我们…

【产品经理修炼之道】- 从需求到功能的转化过程

产品经理的最大作用是将需求转化为产品或者功能,从需求到功能,会经历哪些过程?本文总结了从需求到功能的转化过程,希望对你进一步了解有所帮助。 “大部分的产品经理特别是数字化产品经理其核心价值就是如何去解决如何把需求转化为…

MySQL主键:自增id、UUID、雪花算法

视频可看: 动画讲解:为什么不能使用自增ID或者UUID做MySQL的主键,雪花算法生成的主键存在哪些问题_哔哩哔哩_bilibili 一、MySQL分布式架构中,为什么不能使用自增id作为主键 自增主键的好处:写入效率高 弊端&#x…
最新文章