beego注册登陆忘记修改密码(邮箱验证码)

项目结构:

项目结构如下:
在这里插入图片描述

beego 默认会解析当前应用下的 conf/app.conf 文件。
通过这个文件你可以初始化很多 beego 的默认参数:

1.conf

app.conf
这个目录做一些配置,项目名称、不同运行环境端口、数据库用户名、密码、端口,开启调试等

appname = myapp
httpport = 8080
runmode = dev

1.上面这些参数会替换 beego 默认的一些参数,beego默认的参数请参考链接beego系统默认参数
2.也可以在配置文件中配置应用需要用的一些配置信息,例如:

mysqluser = "root"
mysqlpass = "rootpass"

就可以通过如下的方式获取设置的配置信息:

beego.AppConfig.String("mysqluser")
beego.AppConfig.String("mysqlpass")

3.解析的时候优先解析 runmode 下的配置,然后解析默认的配置
4.INI 格式配置支持 include 方式,引用多个配置文件,例如:

appname = myapp
httpport = 8080
runmode = dev

include "app2.conf"

2.routers

router.go

package routers

import (
	"github.com/astaxie/beego"
	"myapp1/controllers"
)

func init() {
	beego.Router("/register", &controllers.MainController{}, "get:ShowRegister;post:HandleRegister")
	beego.Router("/login", &controllers.LoginController{}, "get:ShowLogin;post:HandleLogin")
	beego.Router("/updatepassword", &controllers.MainController{}, "get:ShowUpdatePassword;post:HandleUpdatePassword")

}

路由包里面我们看到执行了路由注册 beego.Router, 这个函数的功能是映射 URL 到 controller,第一个参数是 URL (用户请求的地址),如果我们注册的有"/",也就是我们访问的不带任何参数的 URL,第二个参数是对应的 Controller,也就是我们即将把请求分发到那个控制器来执行相应的逻辑,例如:

beego.Router("/register", &controllers.MainController{}, "get:ShowRegister;post:HandleRegister")

这样用户就可以通过访问 /register 去执行 MainController 的逻辑。这就是我们所谓的路由

3.controllers

register.go

package controllers

import (
	"github.com/astaxie/beego"
	"log"
	"myapp1/models"
	"strings"
	"time"
)

type MainController struct {
	beego.Controller
}

//register展示页面
func (r *MainController) ShowRegister() {
	r.TplName = "register.html"
}

//register获取数据页面
func (r *MainController) HandleRegister() {
	//获取浏览器传递的值,并去除两边的空格
	Name := strings.TrimSpace(r.GetString("username"))
	Password := strings.TrimSpace(r.GetString("password"))
	Email := strings.TrimSpace(r.GetString("email"))
	//数据处理
	if Name == "" || Password == "" || Email == "" {
		beego.Info("用户名或密码或邮箱不能为空")
		r.Data["errmsg"] = "用户名或密码或邮箱不能为空"
		r.TplName = "register.html"
		return
	}
	//判断用户邮箱是否已经注册过
	_, ok := captchaMap[Email]
	if ok {
		beego.Info("邮箱已存在")
		r.Data["errmsg"] = "邮箱已存在"
		r.TplName = "register.html"
		return
	}

	if err := models.Save(Name, Password, Email); err != nil {
		log.Println("插入数据失败")
	}
	captcha := sendEmail(Email)
	captchaMap[Email] = captcha //将验证码和对应的邮箱存入map
	intCaptcha, _ := r.GetInt("captcha")
	//检验验证码是否正确
	if intCaptcha == captcha { //判断验证码是否正确
		r.Ctx.WriteString("注册成功")
		time.Sleep(1 * time.Second)
		//注册成功返回登陆页面
		r.Redirect("login", 302)
	} else {
		r.Ctx.WriteString("验证码错误")
		return
	}
}

login.go

package controllers

import (
	"github.com/astaxie/beego"
	"myapp1/models"
	"strings"
	"time"
)

type LoginController struct {
	beego.Controller
}

//login展示页面
func (L *LoginController) ShowLogin() {
	L.TplName = "login.html"
}

//login获取数据页面
func (L *LoginController) HandleLogin() {
	//获取浏览器传递的值,并除去两边的空格
	Name := strings.TrimSpace(L.GetString("name"))
	Password := strings.TrimSpace(L.GetString("password"))
	beego.Info("账号:", Name, "密码:", Password)
	//数据处理
	if Name == "" || Password == "" {
		beego.Info("登陆失败")
		L.TplName = "login.html"
		L.Data["errmsg"] = "登陆失败"
		return
	}
	var user models.Users
	//判断用户名是否存在
	user.Name = Name
	err := models.ReadName(Name)
	if err != nil {
		beego.Info("用户名不存在")
		L.TplName = "login.html"
		L.Data["errmsg"] = "用户名不存在"
		return
	}
	//判断密码是不是正确
	if user.Password != Password {
		beego.Info("密码错误")
		time.Sleep(2 * time.Second)
		L.TplName = "login.html"
		L.Data["errmsg"] = "密码错误"
		return
	}
	L.Ctx.WriteString("登录成功")

}

updatepassword.go

package controllers

import (
	"fmt"
	"github.com/astaxie/beego"
	"myapp1/models"
	"strconv"
	"strings"
	"time"
)

//改密码展示页面
func (m *MainController) ShowUpdatePassword() {
	m.TplName = "updatepassword.html"
}

//改密码获取数据页面
func (m *MainController) HandleUpdatePassword() {
	//获取浏览器传递的值
	Name := m.GetString("name")
	Password := m.GetString("password")
	Email := m.GetString("email")
	fmt.Println(Name, Password, Email)
	//数据处理
	if Name == "" || Password == "" || Email == "" {
		beego.Info("用户名或密码或邮箱不能为空")
		m.Data["errmsg"] = "用户名或密码或邮箱不能为空"
		m.TplName = "updatepassword.html"
		return
	}
	if models.Read(Email) != nil {
		beego.Info("用户不存在")
		m.TplName = "updatepassword.html"
		m.Data["errmsg"] = "用户不存在"
		return
	}
	captcha := sendEmail(Email)
	captchaMap[Email] = captcha //将验证码和对应的邮箱存入map
	strCaptcha := strings.TrimSpace(m.GetString("captcha"))
	intCaptcha, _ := strconv.Atoi(strCaptcha)
	//检验验证码是否正确
	if intCaptcha == captcha { //判断验证码是否正确
		err := models.Update(Password) //更新密码
		if err == nil {
			beego.Info("更新密码成功")
			m.Ctx.WriteString("更新密码成功")
			time.Sleep(1 * time.Second)
			m.Redirect("login", 302) //修改密码成功返回登陆页面
		} else {
			beego.Info("更新密码失败")
			m.TplName = "updatepassword.html"
			m.Data["errmsg"] = "更新密码失败"
			return
		}

	}
}

notification.go

package controllers

import (
	"fmt"
	"log"
	"math/rand"
	"net/smtp"
	"time"
)

//定义一个map存放邮箱号和对应的验证码
var captchaMap = make(map[string]int)

//发送验证码邮件
func sendEmail(email string) int {
	auth := smtp.PlainAuth("", "[email protected]", "happy1314WyJ", "smtp.163.com")
	to := []string{email}
	//生成随机验证码
	rand.Seed(time.Now().Unix())
	captcha := rand.Intn(10000)
	str := fmt.Sprintf("From:[email protected]\r\nTo:,%s,\r\nSubject:verifycode\r\n\r\n,%d,\r\n", email, captcha)
	msg := []byte(str)
	err := smtp.SendMail("smtp.163.com:25", auth, "[email protected]", to, msg)
	if err != nil {
		log.Println("邮件发送失败")
	}
	return captcha
}

上面的代码显示首先我们声明了一个控制器 MainController,这个控制器里面内嵌了 beego.Controller,这就是 Go 的嵌入方式,也就是 MainController 自动拥有了所有 beego.Controller 的方法。
beego.Controller 拥有很多方法,其中包括 Init、Prepare、Post、Get、Delete、Head 等方法。如果浏览器的是 GET 请求,那么默认就会执行 MainController 下的 Get 方法。
controllers里面的代码是需要执行的逻辑
我们也可以通过各种方式获取数据,然后赋值到 this.Data 中,这是一个用来存储输出数据的 map,可以赋值任意类型的值,然后需要去渲染的模板,this.TplName 就是需要渲染的模板

4.models

model 层一般用来做数据库操作,我们会在 Model 里面处理一些数据读取

package models

import (
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
)

//用户信息
type Users struct {
	Name     string
	Email    string `orm:"pk"` //设置为主键
	Password string
}

func init() {
	// 参数1   driverName
	// 参数2   数据库类型
	// 这个用来设置 driverName 对应的数据库类型
	// mysql / sqlite3 / postgres 这三种是默认已经注册过的,所以可以无需设置
	_ = orm.RegisterDriver("mysql", orm.DRMySQL)
	//ORM 必须注册一个别名为 default 的数据库,作为默认使用。
	// 参数1        数据库的别名,用来在 ORM 中切换数据库使用
	// 参数2        driverName
	_ = orm.RegisterDataBase("default", "mysql", "root:@tcp(localhost:3306)/test")
	//将你定义的 Model 进行注册,最佳设计是有单独的 models.go 文件,在他的 init 函数中进行注册
	orm.RegisterModel(new(Users))
	//参数1 means table's alias name. default is "default".
	//参数2 means run next sql if the current is error.
	//参数3 means show all info when running command or not.
	//生成表,第二个false要是改成true就会强制更新表,数据全部丢失
	_ = orm.RunSyncdb("default", false, true)

}

func Read(email string) error {
	o := orm.NewOrm()
	//获取查询对象
	var user Users
	//判断邮箱是否存在
	user.Email = email
	err := o.Read(&user, "email") //查询
	return err
}
func ReadName(name string) error {
	o := orm.NewOrm()
	//获取查询对象
	var user Users
	err := o.Read(&user, "name") //查询
	return err
}
func Save(userName, password, email string) error {
	o := orm.NewOrm() // NewOrm 的同时会执行 orm.BootStrap (整个 app 只执行一次),用以验证模型之间的定义并缓存
	//获取插入对象
	user := Users{}
	//插入数值
	user.Name = userName
	user.Password = password
	user.Email = email
	_, err := o.Insert(&user)
	return err
}

func Update(password string) error {
	o := orm.NewOrm() // NewOrm 的同时会执行 orm.BootStrap (整个 app 只执行一次),用以验证模型之间的定义并缓存
	//获取插入对象
	user := Users{}
	_, err := o.Update(&user, "password")
	return err
}

5.views

6.main.go

package main

import (
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	_ "myapp1/routers"
)

func main() {
	//logger := logs.NewLogger(1000)
	//logs.NewConsole()
	//logger.Info("哈哈")
	beego.Run()
}

发布了34 篇原创文章 · 获赞 12 · 访问量 6963

猜你喜欢

转载自blog.csdn.net/weixin_45604257/article/details/102781342