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()
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章