golang关于找回密码功能的递进验证

局部总结的开篇废话

写招新平台之前,写一些小的demo来练手,熟悉整体的框架和思路
但是学业繁重,主要眷顾大学课内的知识巩固,然后一边写算法竞赛的题目,网络编程这边在抽时间研究
这个demo是分成很多阶段来写的,逐渐完善一些初级的功能,所以总结也是写代码之余偶尔写写,并没有专门来整理
然后整理的这些总结呢,是一些自己觉得有意义的点(只是对个人有帮助,对大家仅供参考),个人想写一写自己在
编程时遇到的一些东西,而总结的内容呢,当然也只能是某个部分、不系统的内容…
因为是从零基础开始学习用golang写网站后台,所以代码仅仅是入门功能的实现,也只是记录自己学习路上的一点点经验

递进验证思路

这个部分呢,是因为前端同学希望做成渐进式的验证过程,也就是在一个路由中(/findpwdHandler)进行逐步验证
在这里插入图片描述

  • 第一次验证:username和phonenum (需正确)
  • 第二次验证:question和answer (需正确)
  • 第三次:进行原始密码的修改(确认密码要一致)

那么我在传JSON形式字符串时,就一定要理清代码逻辑,验证成功时才进入下一级验证,而传JSON时千万不要传多了!

效果

golang关于找回密码功能的递进验证_第1张图片
golang关于找回密码功能的递进验证_第2张图片
golang关于找回密码功能的递进验证_第3张图片

代码解释

检索时用到MySQL表中的不完整数据

我写过一个总结,在多个数据的MySQL表格中对部分数据进行检索的方法
(链接:检索MySQL表格不完全数据的小贴士)
所以在开始就定义了一些变量名,而我们知道,在golang语言中,为初始化的变量赋值为零值(也就是说这里的空字符串),但是呢…空字符串通过POST请求读入后端,是按照数据库搜索通过处理的,所以这个时候我多加了一次判断结构,也就是说对刚开始定义(遍历MySQL需要用)但是未赋具体值的变量进行判断,如果是空字符串,就别传JSON了,传了就多了,等到后面进入第二次验证的时候再传!

var password string
var question string
var answer string
username := c.PostForm("username")
phonenum := c.PostForm("phonenum")
fmt.Println("username:", username)
fmt.Println("phonenum:", phonenum)
第一次验证username和phonenum
//核心思想:这些没有赋予具体值的变量,按零值搜索通过处理
err = db.QueryRow("select *from msg where username=? and phonenum=?", username, phonenum).Scan(&username, &password, &phonenum, &question, &answer)
第二次验证question和answer

第二次传密保问题和密保答案是在第一次验证通过的基础上进行的,而为了第一次不接受到第二次验证的JSON(因为第二次需要再传数据下来),我们进行空字符串的判断即可:

question = c.PostForm("question")
answer = c.PostForm("answer")
fmt.Println("question:", question)
fmt.Println("answer:", answer)
if question != "" && answer != "" {
	...
} 

不管怎么验证,都只是代码逻辑思路上的变化,其实本质都是进行MySQL数据库的查找实现,加这个功能的时候其实也没有什么新鲜感,一步一步写下去就OK了

第三步修改密码

最后我定义了newpwd confirm变量,修改密码用到的是MySQL的UPDATE函数,将表格中的数据替换,并不需要写入一个新的行列

stmt, _ := db.Prepare("UPDATE msg SET password=? WHERE username=?")
cg, _ := stmt.Exec(newpwd, temp)
_, err := cg.RowsAffected()

实现的思路就是以上了,关键点也写了处理,就是写总结的内容看上去挺混乱的…也没啥分点,就将就看看了

相对独立关系和关联

  • 相对独立:在第一次的验证时,后端收到前端的数据,验证通过后,给前端返回JSON,前端进行页面的动画跳转,而不关后端的事了。进入第二次验证时,再重复第一次的流程,后端收数据,验证,返回JSON,第三次同理。所以说两次验证+改密码的过程是相对独立的,我想清楚这一点之后,果断删除了自己嵌套了四五层的循环结构,在/findpwdHandler中写了三个独立的部分!
  • 关联:因为变量需要在一开始定义,所以每一次查询会受到影响,也就是空字符当做查找到该数据处理,这时我们就要加空字符的判断!如果是空字符就不要把JSON传了(还没到你的回合呢)
  • 一些处理方法:由于相对独立的关系,到最后修改密码时,我们收不到第一次验证输入的用户名,怎么办呢???解决方法就是我让前端再传一次username过来,也就是下面见到的页面

golang关于找回密码功能的递进验证_第4张图片

POSTMAN 测试

下面是MySQL数据库:
golang关于找回密码功能的递进验证_第5张图片
找到需要修改密码的一栏:
在这里插入图片描述

第一次验证:

golang关于找回密码功能的递进验证_第6张图片
在这里插入图片描述

第二次验证:

在这里插入图片描述
在这里插入图片描述

重置密码

加上了确认密码,相同才行:
在这里插入图片描述
上面这样就时不可行的,下面的情况可以实现:
在这里插入图片描述
在这里插入图片描述

检查数据库

在这里插入图片描述
ok,这样就实现了 忘记密码并修改密码 的功能,思路并不复杂,细节其实也不多,一步一步仔细写就可以实现…更多总结待续…

实属健忘症,都要发布了才想起来代码忘记粘上来:

//gin重构过的代码
func findpwdHandler(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", "*")

	db, err := sql.Open("mysql", "ZWX568:20010225@/user?charset=utf8")
	if err != nil {
		fmt.Println(">>> fail to connect to db <<<")
	}
	defer db.Close()
	fmt.Println(">>> succeed to connect to db <<<")

	var res result
	fmt.Println(">>> findpwd function <<<")
	var password string
	var question string
	var answer string
	username := c.PostForm("username")
	phonenum := c.PostForm("phonenum")
	fmt.Println("username:", username)
	fmt.Println("phonenum:", phonenum)
	var temp string = username
	if username != "" && phonenum != "" {
		err = db.QueryRow("select *from msg where username=? and phonenum=?", username, phonenum).Scan(&username, &password, &phonenum, &question, &answer)
		if err != nil {
			fmt.Println(">>> 1:find pwd fail <<<")
			res.Msg = "findno1"
			c.JSON(http.StatusOK, res)
		} else {
			fmt.Println(">>> 1:find pwd ok <<<")
			res.Msg = "findok1"
			c.JSON(http.StatusOK, res)
		}
	}

	fmt.Println(">>> 2:start <<<")
	question = c.PostForm("question")
	answer = c.PostForm("answer")
	fmt.Println("question:", question)
	fmt.Println("answer:", answer)
	if question != "" || answer != "" {
		err = db.QueryRow("select *from msg where question=? and answer=?", question, answer).Scan(&username, &password, &phonenum, &question, &answer)
		if err != nil {
			fmt.Println(">>> 2:find pwd fail <<<")
			res.Msg = "findno2"
			c.JSON(http.StatusOK, res)
		} else {
			fmt.Println(">>> 2:find pwd ok <<<")
			res.Msg = "findok2"
			c.JSON(http.StatusOK, res)
		}
	}

	fmt.Println(">>> change pwd start <<<")
	newpwd := c.PostForm("newpwd")
	confirm := c.PostForm("confirm")
	if newpwd == "" || confirm == "" {
		return
	}
	fmt.Println("newpwd:", newpwd)
	fmt.Println("confirm:", confirm)

	if newpwd == confirm {
		fmt.Println("username:", temp)
		stmt, _ := db.Prepare("UPDATE msg SET password=? WHERE username=?")
		cg, _ := stmt.Exec(newpwd, temp)
		_, err := cg.RowsAffected()
		var res result
		if err != nil {
			res.Msg = "ChangeNO"
			c.JSON(http.StatusOK, res)
			fmt.Println(">>> Fail to change pwd <<<")
		} else {
			res.Msg = "ChangeOK"
			c.JSON(http.StatusOK, res)
			fmt.Println(">>> Change pwd successfully <<<")
		}
	} else if newpwd != confirm {
		res.Msg = "differ"
		c.JSON(http.StatusOK, res)
	}
}

你可能感兴趣的:(golang关于找回密码功能的递进验证)