看下流程图(由flowchart.js绘制)
表设计
- name 关联用户表,表内唯一
- uuid 随机uuid,并通过sha1 加密
- etime 过期时间
type ForGetPwd struct {
Id int
Name *User `orm:"rel(fk);unique"`
Uuid string
Etime time.Time
}
发送找回密码邮件代码
用户输入邮箱,填写验证码,信息发送到服务端
系统判断前端提交信息,验证是否通过,邮箱是否存在
func (self *UserController) ForGetPwd() {
email, vercode, captcha_id := self.Input().Get("email"), self.Input().Get("vercode"), self.Input().Get("captcha_id")
if !CheckCode(vercode, captcha_id) {
msg := map[string]interface{}{"code": 1, "msg": "验证码错误"}
self.Data["json"] = &msg
self.ServeJSON()
return
}
//通过邮箱判断用户是否存在
if models.IsUserExitByEmail(email) {
_, user := models.FindUserByEmail(email)
uuid := Encrypt(email + Getuuid())
//当前时间
now := time.Now()
//设置过期时间,这里设置1小时后过期
h, _ := time.ParseDuration("1h")
//添加时间
m := now.Add(h)
//是否第一次找回密码,不是则更新表记录的uuid,过期时间,否则添加
if models.IsExitForGetPwdByuser(user.Id) {
forgetpwd := models.FindForGetPwdByuser(user.Id)
forgetpwd.Uuid = uuid
forgetpwd.Etime = m
models.UpdateForGetPwd(&forgetpwd)
} else {
forgetpwd := models.ForGetPwd{Uuid: uuid, Name: &models.User{Id: user.Id}, Etime: m}
models.AddForGetPwd(&forgetpwd)
}
//发送找回密码邮件
url := "http://192.168.1.12:8080/forgetpwd/?uuid=" + uuid
SendMail(email, "<h2>请点击以下链接重置密码,如非本人操作请忽略:</h2><p><a href="+url+">"+url+"</a>", "重置密码")
msg := map[string]interface{}{"code": 0, "msg": "success"}
self.Data["json"] = &msg
self.ServeJSON()
} else {
msg := map[string]interface{}{"code": 1, "msg": "邮箱不存在"}
self.Data["json"] = &msg
self.ServeJSON()
}
}
用户收到邮件,点击链接重置密码
把uuid回传到重设密码页面,以便前端发送uuid
func (self *UserController) ForGetPwdPage() {
//用户点击重置密码链接,需要把uuid回传
uuid := self.Input().Get("uuid")
self.Data["uuid"] = uuid
self.TplName = "user/forgetpwd.html"
}
//更新密码
func (self *UserController) SetNewPwd() {
uuid, password := self.Input().Get("uuid"), self.Input().Get("password")
now := time.Now()
//检测uuid是否有效,有效便更新密码,否则直接返回
if models.CheckForGet(uuid, now) {
//通过uuid查找对应要修改密码的用户
u := models.FindForGetPwdByUuid(uuid)
user := models.FindUserDetialById(u.Name.Id)
user.Password = password
models.UpdateUser(&user)
msg := map[string]interface{}{"code": 0, "msg": "success"}
self.Data["json"] = &msg
self.ServeJSON()
}
msg := map[string]interface{}{"code": 1, "msg": "invalid token"}
self.Data["json"] = &msg
self.ServeJSON()
}
检测uuid是否有效
//检测uuid是否过期
func CheckForGet(uuid string, t time.Time) bool {
o := orm.NewOrm()
var forgetpwd ForGetPwd
return o.QueryTable(forgetpwd).Filter("UUID", uuid).Filter("Etime__gte", t).Exist()
}
js代码片段
layui.define(['layer', 'form'], function(exports) {
var layer = layui.layer
var form = layui.form()
var $ = layui.jquery
form.verify({
password: [/(.+){6,12}$/, '密码必须6到12位'],
});
form.on('submit(forgetpwd)', function(data) {
if (data.field.password != data.field.repassword) {
layer.msg("两次密码输入不一致!")
return false;
}
$.ajax({
async: false,
url: "/user/setnewpwd",
data: {
"password": data.field.password,
"repassword":data.field.password,
"uuid":data.field.uuid,
},
type: 'POST',
success: function(text) {
if (text.msg == 'success') {
location.href = '/'
} else if (text.code != 0) {
layer.msg(text.msg)
}
}
});
return false;
});
exports('forgetpwd', {});
});