當主頁面成功展現以後咱們開始作一個簡單的登錄系統css
1、 登錄功能html
登錄的時候咱們須要保存用戶的登錄狀態,這個時候咱們就要用到session了mysql
beego官方支持文件、緩存、數據庫幾種保存session的方式我選擇了mysql數據庫方式git
這個時候就要用到app.conf下面的這幾個參數了github
sessionon = truesql
sessionhashkey = "asdsdfsdfsdfsfdsf"數據庫
sessionprovider = "mysql"bootstrap
sessionname = "servesession"緩存
sessionname和sessionhashkey是自定義的session
首先你須要手動在你項目相關的數據庫表中建立session這個表
官方給出的sql建立語是
CREATE TABLE `session` ( `session_key` char(64) NOT NULL, `session_data` blob, `session_expiry` int(11) unsigned NOT NULL, PRIMARY KEY (`session_key`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
後續我會將它寫成自定義命令來方便部署項目
建立好數據庫表後,咱們在main.go下面註冊這個session表
func init() { if sessionprovider, err := beego.GetConfig("String", "sessionprovider", "--"); err == nil && sessionprovider == "mysql" { dbname, _ := beego.GetConfig("String", "dbname", "myblogbygo") sqluser, _ := beego.GetConfig("String", "sqluser", "root") sqlpass, _ := beego.GetConfig("String", "sqlpass", "123") sqlhost, _ := beego.GetConfig("String", "sqlhost", "127.0.0.1") sqlport, _ := beego.GetConfig("String", "sqlport", "3306") verification := "%s:%s@tcp(%s:%s)/%s?charset=utf8" verificationStr := fmt.Sprintf(verification, sqluser, sqlpass, sqlhost, sqlport, dbname) beego.BConfig.WebConfig.Session.SessionProviderConfig = verificationStr } }
接下來你就能夠嘗試在contorllers函數下面嘗試
c.SetSession("isLogin", bool(true))和c.GetSession("isLogin")來嘗試是否能夠寫入和或許相對應的session
c.SetSession("isLogin", bool(true)) islogin := c.GetSession("isLogin") fmt.Println("sessionValue", islogin)
成功後接下來開始寫登錄功能
首先自定義一個初始化用戶的自定義命令,由於beego自己是支持命令模式的,只須要在main.go中的main函數執行以下代碼
orm.RunCommand()
既然如此咱們拓展下這個命令模式,咱們建立一個tools文件夾用來放自定義的拓展功能,在下面建立一個叫commands.go的文件
/tools/commands.go代碼以下
package tools import ( "crypto/sha512" "encoding/base64" "fmt" "os" "github.com/astaxie/beego/orm" "MyblogByGo/models" ) // 將其設計爲map便於拓展功能 var commandMaps = map[string]func(){ "initUser": initUser, "initSession": initSessionTable, } // initUser 初始化管理員 func initUser() { user := new(models.User) user.Name = "你的用戶名" userpass := "你的密碼" myHs := sha512.New() //使用sha512加密方式 myHs.Write([]byte(userpass)) myHasPas := myHs.Sum(nil) //這個時候將密碼變爲亂碼,返回的是byte類型 encodedPss := base64.StdEncoding.EncodeToString([]byte(myHasPas)) //將byte類型轉爲字符串便於存儲 user.PassWord = encodedPss o := orm.NewOrm() o.Using("default") if id, err := o.Insert(user); err == nil { fmt.Println("用戶已經建立:", user.Name, id) } else { fmt.Println("error:", err) } } //順便將以前的建立session表也自定義爲命令 func initSessionTable() { o := orm.NewOrm() o.Using("default") sqlstr := "CREATE TABLE `session` " + "(`session_key` char(64) NOT NULL,`session_data` blob, `session_expiry` int(11) unsigned NOT NULL,PRIMARY KEY (`session_key`)) " + "ENGINE=MyISAM DEFAULT CHARSET=utf8;" r := o.Raw(sqlstr) _, cerr := r.Exec() if cerr == nil { fmt.Println("session table create success") } else { fmt.Println("session table create err:", cerr) } } // Mycommands 自定義命令 func cMycommands(com func()) { if len(os.Args) < 2 { return } else if mcom, ok := commandMaps[os.Args[1]]; ok { mcom() os.Exit(0) } else { com() } }
頁面一樣咱們直接搬bootstrap4的模版第一部分有提到
將這個頁面放到views/blog下面取名叫signin.html並導入相應的依賴腳本。
接下來在controllers下面新建文件叫account.go用來放置和登錄驗證相關的代碼
/controllers/account.go
package controllers import ( "crypto/sha512" "encoding/base64" "fmt" "html/template" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" "MyblogByGo/models" ) // AccountController 登錄入口 type AccountController struct { beego.Controller } // Get Signin blog展現登錄頁面 func (c *AccountController) Get() { c.Data["xsrfdata"] = template.HTML(c.XSRFFormHTML()) c.TplName = "blog/signin.html" } // 用於獲取form表單的struct type userFrom struct { Username string `form:"username"` Pass string `form:"pass"` } // Post post signin func (c *AccountController) Post() { uf := userFrom{} 將數據解析到userForm struct中 if err := c.ParseForm(&uf); err != nil { fmt.Println("數據提交出錯:", err) } else { user := models.User{ Name: uf.Username, } o := orm.NewOrm() o.Using("default") err := o.Read(&user, "Name") if err == orm.ErrNoRows { fmt.Println("查詢不到用戶:", user.Name) c.Data["errmsg"] = "找不到用戶" c.Data["xsrfdata"] = template.HTML(c.XSRFFormHTML()) c.TplName = "blog/signin.html" } else if err == orm.ErrMissPK { fmt.Println("找不到主鍵") c.Data["xsrfdata"] = template.HTML(c.XSRFFormHTML()) c.TplName = "blog/signin.html" } else { ufpass := uf.Pass myHs := sha512.New() myHs.Write([]byte(ufpass)) myHasPas := myHs.Sum(nil) encodedPss := base64.StdEncoding.EncodeToString([]byte(myHasPas)) if user.PassWord == encodedPss { c.SetSession("isLogin", bool(true)) c.SetSession("userId", int(user.Id)) // c.SetSession("userid", user.Id) c.Redirect("/", 302) } else { c.Data["errmsg"] = "密碼錯誤" c.TplName = "blog/signin.html" } } } } // SignOutController 退出登陸 type SignOutController struct { beego.Controller } // Get 退出登陸 func (c *SignOutController) Get() { c.DestroySession() url := beego.URLFor("AccountController.Get") c.Redirect(url, 302) }
在views/blog 下面建立signin.html代碼以下
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="/static/img/blog/favicon.ico"> <title>Signin</title> <!-- Bootstrap core CSS --> <link href="/static/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom styles for this template --> <link href="/static/css/blog/signin.css" rel="stylesheet"> </head> <body class="text-center"> <form class="form-signin" method="POST" action="/signin" id="user"> {{ .xsrfdata }} <img class="mb-4" src="/static/img/blog/UNADJUSTEDNONRAW_thumb_19a.jpg" alt="" width="72" height="72"> <h1 class="h3 mb-3 font-weight-normal">請登陸</h1> <label for="username" class="sr-only">Username</label> <input name="username" type="text" id="username" class="form-control" placeholder="username" required autofocus> <label for="pass" class="sr-only">Password</label> <input name="pass" type="password" id="pass" class="form-control" placeholder="password" required> {{if .errmsg}} <!-- 展現錯誤信息 --> <p style="color: red">{{.errmsg}}</p> {{end}} <!-- <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me"> Remember me </label> </div> --> <button class="btn btn-lg btn-primary btn-block" type="submit">登陸</button> <p class="mt-5 mb-3 text-muted">© 2019-2020 by Space Cowboy</p> </form> </body> </html>
注意由於在配置文件中啓用了xsrf防禦,在訪問登錄頁面的時候將生成的xsfr from傳入了模版,並用模版渲染了,詳細看官方文檔
這個時候登錄準備好了,接下來將以前建立的全部表所有在數據庫中生成
在mian.go中導入models文件
import (
...
...
_ "MyblogByGo/models"
)
注意在導入的包前面加了一個 _ 是爲了執行包中的init函數,這是一個特殊語法,由於我將註冊數據庫一系列操做放到了init函數裏面了。
先啓動數據庫,這個時候執行go run main.go orm syncdb 就會建立好表,注意數據庫登錄配置不要出錯了。
成功後命令行就會顯示已經建立表
create table your table name
...
...
當這些都準備好了,就能夠執行咱們以前的自定義命令 go run main.go initUser來初始化一個用戶了
註冊好登錄頁面路由
beego.Router("/signin", &controllers.AccountController{})
這個時候就能夠進入你的登錄頁嘗試你註冊的用戶能不能登錄了,注意以前的代碼登錄成功後將跳轉到主頁
登錄頁面展現:
那個頭像是自定義的