局部总结的开篇废话

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

递进验证思路

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

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

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

检索时用到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过来,也就是下面见到的页面

POSTMAN 测试

下面是MySQL数据库:
在这里插入图片描述
找到需要修改密码的一栏:
在这里插入图片描述

第一次验证:

第二次验证:

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

检查数据库

在这里插入图片描述
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)
                    局部总结的开篇废话更新一篇局部小总结的一个开头废话写招新平台之前,写一些小的demo来练手,熟悉整体的框架和思路但是学业繁重,主要眷顾大学课内的知识巩固,然后一边写算法竞赛的题目,网络编程这边在抽时间研究这个demo是分成很多阶段来写的,逐渐完善一些初级的功能,所以总结也是写代码之余偶尔写写,并没有专门来整理然后整理的这些总结呢,是一些自己觉得有意义的点(只是对个人有帮助,对大家仅供参...
				
Google账号找回通用方法【尤其是知道账号密码仍无法登录和找回的】普通找回注意:适用于常用谷歌账户的设备和网络情况下无法使用手机或辅助邮箱验证码进行密码找回特殊找回方法注意;适用于1.新的设备以及网络环境(包括由于非正常原因导致设备系统以及应用信息变更)2.没有开启辅助验证(手机/邮箱)3.知道账号密码但无法登录或找回。通过申诉进行找回 普通找回 注意:适用于 常用谷歌账户的设备和网络情况下 无法使用手机或辅助邮箱验证码进行密码找回 通过恢复页面进行恢复 https://accounts.google
框架:github.com/gin-gonic/gin 验证码:github.com/dchest/captcha session管理:github.com/gorilla/sessions + github.com/boj/redistore OTP:privacyidea + github.com/xlzd/gotp 邮件发送:gopkg.in/gomai... CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL DEFAULT '', `password` varchar(50) NOT NULL DEFAULT '', `nickname` varchar(50) NOT NULL DEFAULT '', `created_at` timestamp NOT NULL DEFAULT CURRENT
用户名和密码验证界面 Go语言作为后端语言常用的应用,最简单的就是做一个后端的用户名和密码验证了,这相当于后端的hello world,所以做一个简单的json验证的后端界面吧 这是路径↓,post是用post方法来发送数据 [POST]/login "username": "admin", "password": "123456", "token": "TOKEN" 如果TOKEN不对,返回json "code": 404 如果TOKEN对
SMTP服务器就是邮件代收发服务器,由邮件服务商提供,常见的SMTP服务器端口号: QQ邮箱:SMTP服务器地址:smtp.qq.com(端口:587) 雅虎邮箱: SMTP服务器地址:smtp.yahoo.com(端口:587) 163邮箱:SMTP服务器地址:smtp.163.com(端口:25) 126邮箱: SMTP服务器地址:smtp.126.com(端口:2...
Go语言实现登录验证,有3次机会,如果用户名为 zhangsan ,密码为 123456 ,则提示登录成功,否则提示还有几次机会,次数用完,提示登录失败。代码如下: package main import "fmt" func main() { var name string var pwd string var loginChance = 3 for i := 1; i <=...
"fmt" "github.com/go-playground/locales/zh" ut "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" zhtranslations "github.com/go-pla func login(username, password string) bool { // 检查用户名是否存在 if storedPassword, ok := users[username]; ok { // 检查密码是否正确 if storedPassword == password { return true return false func main() { // 测试登录功能 username := "alice" password := "123456" if login(username, password) { fmt.Printf("%s 登录成功\n", username) } else { fmt.Printf("%s 登录失败\n", username) 在上面的代码中,我们定义了一个名为`login`的函数,用于检查给定的用户名和密码是否匹配。我们使用一个名为`users`的map来存储用户名和密码的对应关系。在`login`函数中,我们首先检查给定的用户名是否存在于`users`中,如果存在,我们再检查密码是否匹配。如果用户名和密码都匹配,该函数返回`true`,否则返回`false`。 在`main`函数中,我们使用`login`函数测试了一个用户的登录过程。我们将一个用户名和密码作为参数传递给`login`函数,并根据函数的返回值输出相应的结果。 请注意,这只是一个简单的示例,实际应用中需要更复杂的用户认证策略。