github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/routers/ForgotHandler.go (about) 1 package routers 2 3 import ( 4 "encoding/base64" 5 "fmt" 6 "github.com/insionng/makross" 7 8 "strconv" 9 "strings" 10 "time" 11 "github.com/insionng/yougam/helper" 12 simplejson "github.com/insionng/yougam/libraries/bitly/go-simplejson" 13 "github.com/insionng/yougam/models" 14 ) 15 16 func GetForgotHandler(self *makross.Context) error { 17 18 19 self.Set("catpage", "ForgotHandler") 20 tplname := "forgot" 21 22 var keyin string 23 if keyin = self.Param("key").String(); len(keyin) <= 0 { 24 keyin = self.FormValue("key") 25 } 26 27 userkey := helper.MD5to16(self.RealIP()) 28 29 switch { 30 case ((len(keyin) > 0) && (len(userkey) > 0)): 31 { 32 33 keybyte, e := base64.URLEncoding.DecodeString(keyin) 34 if e != nil { 35 self.Flash.Error("抱歉,取回密码认证链接非法!") 36 goto render 37 } 38 keyin = string(keybyte) 39 if s, err := helper.Aes128COMDecrypt(keyin, helper.AesConstKey); err != nil { 40 41 self.Flash.Error("抱歉,取回密码认证链接不合法!!") 42 goto render 43 44 } else { 45 if s == "" { 46 self.Flash.Error("抱歉,取回密码认证失败!") 47 goto render 48 } 49 if sjson, err := simplejson.NewJson([]byte(s)); err != nil { 50 51 self.Flash.Error("抱歉,取回密码认证失败!!") 52 goto render 53 } else { 54 55 data := sjson.Get("data").MustMap() 56 if data == nil { 57 self.Flash.Error("抱歉,取回密码认证失败!!!") 58 59 goto render 60 } 61 62 var key, email, randkey, timekey string 63 if data["key"] != nil { 64 key = data["key"].(string) 65 } 66 if data["email"] != nil { 67 email = data["email"].(string) 68 } 69 if data["randkey"] != nil { 70 randkey = data["randkey"].(string) 71 } 72 if data["timekey"] != nil { 73 timekey = data["timekey"].(string) 74 } 75 76 timekeyInt64, _ := strconv.ParseInt(timekey, 10, 0) 77 key2 := helper.SHA1(randkey + userkey + email + helper.AesConstKey + timekey) 78 if now := time.Now().Unix(); timekeyInt64 < now { //超时 79 80 self.Flash.Error("抱歉,该认证链接已经超时失效!") 81 goto render 82 } 83 if key == key2 { 84 85 tplname = "password" 86 self.Set("fmail", email) 87 88 if usr, e := models.GetUserByEmail(email); usr != nil && e == nil { 89 tplname = "password" 90 self.Flash.Success("恭喜,该次链接校验成功,请设置密码!") 91 goto render 92 } else { 93 94 self.Flash.Error("抱歉,该Email并没有用作注册账号!") 95 goto render 96 } 97 } else { 98 99 self.Flash.Error("抱歉,该认证链接验证失败!") 100 goto render 101 } 102 103 } 104 } 105 } 106 default: 107 { 108 tplname = "forgot" 109 goto render 110 } 111 } 112 render: 113 return self.Render(tplname) 114 } 115 116 func PostForgotHandler(self *makross.Context) error { 117 118 119 self.Set("catpage", "ForgotHandler") 120 tplname := "forgot" 121 var keyin string 122 if keyin = self.Param("key").String(); len(keyin) <= 0 { 123 keyin = self.FormValue("key") 124 } 125 126 userkey := helper.MD5to16(self.RealIP()) 127 128 switch { 129 case ((len(keyin) > 0) && (len(userkey) > 0)): //进入重置密码分支 130 { 131 132 keybyte, e := base64.URLEncoding.DecodeString(keyin) 133 if e != nil { 134 self.Flash.Error("抱歉,取回密码认证链接非法!") 135 goto render 136 } 137 keyin = string(keybyte) 138 if s, err := helper.Aes128COMDecrypt(keyin, helper.AesConstKey); err != nil { 139 140 self.Flash.Error("抱歉,取回密码认证链接不合法!!") 141 goto render 142 143 } else { 144 if len(s) == 0 { 145 self.Flash.Error("抱歉,取回密码认证失败!") 146 goto render 147 } 148 if sjson, err := simplejson.NewJson([]byte(s)); err != nil { 149 150 self.Flash.Error("抱歉,取回密码认证失败!!") 151 goto render 152 } else { 153 154 data := sjson.Get("data").MustMap() 155 if data == nil { 156 self.Flash.Error("抱歉,取回密码认证失败!!!") 157 goto render 158 } 159 160 var key, email, randkey, timekey string 161 if data["key"] != nil { 162 key = data["key"].(string) 163 } 164 if data["email"] != nil { 165 email = data["email"].(string) 166 } 167 if data["randkey"] != nil { 168 randkey = data["randkey"].(string) 169 } 170 if data["timekey"] != nil { 171 timekey = data["timekey"].(string) 172 } 173 174 timekeyInt64, _ := strconv.ParseInt(timekey, 10, 0) 175 key2 := helper.SHA1(randkey + userkey + email + helper.AesConstKey + timekey) 176 if now := time.Now().Unix(); timekeyInt64 < now { //超时 177 self.Flash.Error("抱歉,该认证链接已经超时失效!") 178 goto render 179 } 180 if key == key2 { 181 182 tplname = "password" 183 self.Set("fmail", email) 184 185 if usr, e := models.GetUserByEmail(email); usr != nil && e == nil { 186 tplname = "password" 187 password := self.FormValue("password") 188 repassword := self.FormValue("repassword") 189 if len(password) == 0 { 190 self.Flash.Error("密码不能设置为空!") 191 goto render 192 } 193 194 if password == repassword { 195 usr.Password = helper.EncryptHash(password, nil) 196 197 if rows, e := models.PutUser(usr.Id, usr); rows <= 0 || e != nil { 198 199 self.Flash.Error("抱歉,服务器写入数据发送错误,请你稍后重新尝试.") 200 goto render 201 } else { 202 203 self.Flash.Success("恭喜,你已经成功设置新密码!") 204 goto render 205 } 206 } else { 207 self.Flash.Error("抱歉,新设置密码与确认密码不一致,请你修改后重新尝试.") 208 goto render 209 } 210 } else { 211 212 self.Flash.Error("抱歉,该Email并没有用作注册账号!") 213 goto render 214 } 215 } else { 216 217 self.Flash.Error("抱歉,该认证链接验证失败!") 218 goto render 219 } 220 221 } 222 } 223 } 224 default: //发送认证链接邮件分支 225 { 226 var email string 227 if email = strings.TrimSpace(self.Param("email").String()); len(email) <= 0 { 228 email = strings.TrimSpace(self.FormValue("email")) 229 } 230 231 if len(email) <= 0 { 232 self.Flash.Error("抱歉,提交的邮件地址不能为空!") 233 goto render 234 } 235 236 randkey := helper.GUID32BIT() 237 d, _ := time.ParseDuration("1h") //设为1小时后失效 238 timekey := strconv.FormatInt(time.Now().Add(d).UnixNano(), 10) 239 key := helper.SHA1(randkey + userkey + email + helper.AesConstKey + timekey) 240 241 m := map[string]string{} 242 m["key"] = key 243 m["email"] = email 244 m["randkey"] = randkey //string 245 m["timekey"] = timekey //string 246 247 crypted, _ := helper.SetJsonCOMEncrypt(1, "", m) 248 b64key := base64.URLEncoding.EncodeToString([]byte(crypted)) 249 250 if helper.CheckEmail(email) { 251 252 if usr, e := models.GetUserByEmail(email); usr != nil && e == nil { 253 254 url := fmt.Sprintf("http://%s/forgot/?key=%s", helper.Domain, b64key) 255 body := "<html><body><div>" 256 body = body + "<p>亲爱的 <strong>" + usr.Username + "</strong> ,您好:</p>" 257 body = body + `<p style="padding-left:2em;">您申请了重置` + helper.SiteName + `登录密码,请点击以下链接设置新密码.</p>` 258 body = body + `<p><a href="` + url + `" target="_blank">` + url + `</a></p>` 259 body = body + "<p>(如果无法点击该URL链接地址,请将它复制并粘帖到浏览器的地址输入框访问即可.)</p>" 260 body = body + "<p>注意:请您在收到邮件后点击此链接以完成重置,否则该链接将会在1小时后失效.</p>" 261 body = body + "<p>我们将一如既往竭诚为您服务!</p>" 262 body = body + `<p style="border-bottom:dotted 1px gray;height:1px;"></p>` 263 body = body + "<p>" + helper.MailAdline + "</p>" 264 body = body + "</div></body></html>" 265 266 subject := "【" + helper.SiteName + "】找回密码" 267 268 //发送邮件 269 if err := helper.SendEmail(email, subject, body, "html"); err != nil { 270 self.Flash.Error("抱歉," + helper.SiteName + "发送重置邮件失败,请你稍后重新尝试.") 271 goto render 272 } else { 273 self.Flash.Success("恭喜," + helper.SiteName + "已经发送重置邮件到你的注册邮箱,请你注意查收.") 274 goto render 275 } 276 277 } else { 278 self.Flash.Error("抱歉,该Email并没有用作注册账号!") 279 return self.Redirect("/forgot/") 280 } 281 } else { 282 self.Flash.Error("抱歉,你提交的邮件地址不合法!") 283 goto render 284 } 285 } 286 } 287 render: 288 return self.Render(tplname) 289 }