beego 是一個用于Go編程語言的開源、高性能的 web 框架
beego 被用于在Go語言中企業應用程序的快速開發,包括RESTful API、web應用程序和后端服務。它的靈感來源于Tornado, Sinatra 和 Flask
beego 官網:http://beego.gocn.vip/
上面的 beego 官網如果訪問不到,看這篇文章《beego 官網文檔本地環境搭建》
注意:本文的 beego 文檔使用的就是本地環境搭建的文檔,因為官網文檔已經不可用了
beego 官方 github 倉庫:https://github.com/beego/beego
上一講,講了 beego 頁面視圖,需要的朋友可以查看《Beego 使用教程 7:Web 文件上傳下載和錯誤處理》
這一講,講解 session 和 cookie。代碼使用上一講的代碼
目錄
1、Session 使用
1.1、基本使用
1.3、修改 session 存儲位置
1.4、修改 session 存儲在 redis
2、Cookie 使用
2.1、普通 Cookie 處理
2.2、加密 Cookie 處理
1、Session 使用
beego 內置了 session 模塊,目前 session 模塊支持的后端引擎包括 memory、cookie、file、mysql、redis、couchbase、memcache、postgres,用戶也可以根據相應的接口實現自己的引擎
使用 session 前需要先開啟,可通過代碼設置或配置文件開啟
web.BConfig.WebConfig.Session.SessionOn = true
配置文件配置,在 app.conf 中配置
sessionon = true
筆者使用在配置文件中配置的方式
1.1、基本使用
默認session 存儲在 內存中
app.conf 配置文件開啟 session 使用
在 controller 目錄下新建 session.go ,代碼是下面內容
package controllerimport ("github.com/beego/beego/v2/server/web""strconv"
)type SessionController struct {web.Controller
}func (this *SessionController) GetUserInfo() {user := this.GetSession("user")if user == nil {this.SetSession("user", int(1))} else {this.SetSession("user", user.(int)+1)}res := "ok"if user != nil {res = res + strconv.Itoa(user.(int))}this.Ctx.WriteString(res)
}
GetSession 獲取session,SetSession 往session 中添加數據,更多的 session 相關方法看下圖
在 main.go 中添加?GetUserInfo 的路由
package mainimport ("beego-demo/controller""beego-demo/filter""fmt""github.com/beego/beego/v2/core/config""github.com/beego/beego/v2/server/web""github.com/beego/beego/v2/server/web/context""html/template""net/http"
)func main() {//通過config獲取自定義配置workername, _ := config.String("workername")fmt.Println(workername)//執行定時任務//go job.DemoTask()//注冊自動路由//web.AutoPrefix("api", &controller.UserController{})web.CtrlGet("/name", (*controller.UserController).Name)web.CtrlGet("/get/:id", (*controller.UserController).GetUserById)web.CtrlGet("/get/:id/:num", (*controller.UserController).GetUserByIdAndNum)//返回頁面web.CtrlGet("/page/index", (*controller.PageController).Index)web.CtrlGet("/page/f", (*controller.PageController).F)web.CtrlGet("/page/main", (*controller.PageController).Main)//web輸入參數web.CtrlGet("/pathparam/:name", (*controller.ParamController).PathParam)web.CtrlGet("/getparam", (*controller.ParamController).GetParam)web.CtrlPost("/postparam", (*controller.ParamController).PostParam)web.CtrlPost("/bindparam", (*controller.ParamController).BindParam)//上傳文件web.CtrlPost("/upload", (*controller.FileController).Upload)//下載文件web.CtrlGet("/download", (*controller.FileController).Download)//錯誤處理web.CtrlGet("/getUserName", (*controller.ErrorHandlerController).GetUserName)web.CtrlGet("/getUserAge", (*controller.ErrorHandlerController).GetUserAge)web.CtrlGet("/getUserAddr", (*controller.ErrorHandlerController).GetUserAddr)web.CtrlGet("/getUserGender", (*controller.ErrorHandlerController).GetUserGender)//注冊錯誤處理函數web.ErrorController(&controller.ErrorController{})//sessionweb.CtrlGet("/getUserInfo", (*controller.SessionController).GetUserInfo)//注冊函數式路由controller.RegisterFunctionalRoutes()//web命名空間controller.RegisterNamespaceRoutes()//過濾器filter.RegisterFilters()//開啟 Admin 管理后臺web.BConfig.Listen.EnableAdmin = trueweb.BConfig.Listen.AdminAddr = "localhost"web.BConfig.Listen.AdminPort = 8088//web.BConfig.WebConfig.ViewsPath = "pages"//開啟post 請求 bind綁定請求體web.BConfig.CopyRequestBody = true//查看已注冊路由tree := web.PrintTree()methods := tree["Data"].(web.M)for k, v := range methods {fmt.Printf("%s => %v\n", k, v)}//自定義模板函數web.AddFuncMap("bookName", bookName)//自定義401返回web.ErrorHandler("401", page401)//自定義404返回web.ErrorHandler("404", page404)web.ErrorHandler("dbError", dbError)web.BConfig.RecoverFunc = func(context *context.Context, config *web.Config) {if err := recover(); err != nil {context.WriteString(fmt.Sprintf("you panic, err: %v", err))}}web.Run()
}// 自定義模板函數添加書名號
func bookName(in string) (out string) {out = "《" + in + "》"return
}func page401(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("401.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/401.html")data := make(map[string]interface{})data["content"] = "沒有訪問權限"t.Execute(rw, data)
}func page404(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("404.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/404.html")data := make(map[string]interface{})data["content"] = "頁面沒找到"t.Execute(rw, data)
}func dbError(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("dberror.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/dberror.html")data := make(map[string]interface{})data["content"] = "我是自定義字符串錯誤類型處理函數"t.Execute(rw, data)
}
運行效果
瀏覽器訪問:http://localhost:9090/getUserInfo
1.2、修改?cookies 名稱
Session 默認是保存在用戶的瀏覽器 cookies 里面的,默認名是 beegosessionID
通過代碼?web.BConfig.WebConfig.Session.SessionName 設置,或配置?sessionname
筆者使用配置?sessionname 修改 cookie 名稱,改成?JSESSIONID
默認的名稱可以通過訪問后,瀏覽器F12打開開發者工具查看,看下圖
修改后重啟項目,重新打開瀏覽器,訪問:http://localhost:9090/getUserInfo
1.3、修改 session 存儲位置
默認 session 存儲在內存 memory 中,可以修改其存儲在?file、mysql、redis 等
通過代碼?web.BConfig.WebConfig.Session.SessionProvider 或配置文件參數?sessionprovider 修改
筆者下面講解獎session 存儲在 file 中,筆者使用配置文件的方式
# 設置 Session 的引擎,默認是 memory,目前支持還有 file、mysql、redis 等
sessionprovider = file
# 設置對應 file、mysql、redis 引擎的保存路徑或者鏈接地址,默認值是空
sessionproviderconfig = E:\tmp\file\session
app.conf 文件內容看下圖
重啟項目,訪問:http://localhost:9090/getUserInfo
1.4、修改 session 存儲在 redis
將 session 存儲在 redis 比較常見,下面說明
redis 相關配置
sessionprovider = redis
# Redis 配置信息如下所示 表示鏈接的地址,連接池,訪問密碼,沒有保持為空
sessionproviderconfig = "127.0.0.1:6379,10,123456"
redis 密碼配置在配置信息中?
添加 beego redis 依賴,在項目根目錄執行下面命令
go get github.com/beego/beego/v2/server/web/session/redis
再執行下面命令
go mod tidy
在 main.go 中匿名引入 redis 引擎對應的包
_ "github.com/beego/beego/v2/server/web/session/redis"
main.go 代碼
package mainimport ("beego-demo/controller""beego-demo/filter""fmt""github.com/beego/beego/v2/core/config""github.com/beego/beego/v2/server/web""github.com/beego/beego/v2/server/web/context"_ "github.com/beego/beego/v2/server/web/session/redis""html/template""net/http"
)func main() {//通過config獲取自定義配置workername, _ := config.String("workername")fmt.Println(workername)//執行定時任務//go job.DemoTask()//注冊自動路由//web.AutoPrefix("api", &controller.UserController{})web.CtrlGet("/name", (*controller.UserController).Name)web.CtrlGet("/get/:id", (*controller.UserController).GetUserById)web.CtrlGet("/get/:id/:num", (*controller.UserController).GetUserByIdAndNum)//返回頁面web.CtrlGet("/page/index", (*controller.PageController).Index)web.CtrlGet("/page/f", (*controller.PageController).F)web.CtrlGet("/page/main", (*controller.PageController).Main)//web輸入參數web.CtrlGet("/pathparam/:name", (*controller.ParamController).PathParam)web.CtrlGet("/getparam", (*controller.ParamController).GetParam)web.CtrlPost("/postparam", (*controller.ParamController).PostParam)web.CtrlPost("/bindparam", (*controller.ParamController).BindParam)//上傳文件web.CtrlPost("/upload", (*controller.FileController).Upload)//下載文件web.CtrlGet("/download", (*controller.FileController).Download)//錯誤處理web.CtrlGet("/getUserName", (*controller.ErrorHandlerController).GetUserName)web.CtrlGet("/getUserAge", (*controller.ErrorHandlerController).GetUserAge)web.CtrlGet("/getUserAddr", (*controller.ErrorHandlerController).GetUserAddr)web.CtrlGet("/getUserGender", (*controller.ErrorHandlerController).GetUserGender)//注冊錯誤處理函數web.ErrorController(&controller.ErrorController{})//sessionweb.CtrlGet("/getUserInfo", (*controller.SessionController).GetUserInfo)//注冊函數式路由controller.RegisterFunctionalRoutes()//web命名空間controller.RegisterNamespaceRoutes()//過濾器filter.RegisterFilters()//開啟 Admin 管理后臺web.BConfig.Listen.EnableAdmin = trueweb.BConfig.Listen.AdminAddr = "localhost"web.BConfig.Listen.AdminPort = 8088//web.BConfig.WebConfig.ViewsPath = "pages"//開啟post 請求 bind綁定請求體web.BConfig.CopyRequestBody = true//查看已注冊路由tree := web.PrintTree()methods := tree["Data"].(web.M)for k, v := range methods {fmt.Printf("%s => %v\n", k, v)}//自定義模板函數web.AddFuncMap("bookName", bookName)//自定義401返回web.ErrorHandler("401", page401)//自定義404返回web.ErrorHandler("404", page404)web.ErrorHandler("dbError", dbError)web.BConfig.RecoverFunc = func(context *context.Context, config *web.Config) {if err := recover(); err != nil {context.WriteString(fmt.Sprintf("you panic, err: %v", err))}}web.Run()
}// 自定義模板函數添加書名號
func bookName(in string) (out string) {out = "《" + in + "》"return
}func page401(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("401.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/401.html")data := make(map[string]interface{})data["content"] = "沒有訪問權限"t.Execute(rw, data)
}func page404(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("404.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/404.html")data := make(map[string]interface{})data["content"] = "頁面沒找到"t.Execute(rw, data)
}func dbError(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("dberror.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/dberror.html")data := make(map[string]interface{})data["content"] = "我是自定義字符串錯誤類型處理函數"t.Execute(rw, data)
}
啟動 redis 后,瀏覽器請求:http://localhost:9090/getUserInfo
可在redis 中查看session 信息,筆者使用 redis 工具查看
2、Cookie 使用
Beego 通過Context直接封裝了對普通 Cookie 的處理方法,可以直接使用
2.1、普通 Cookie 處理
修改 session.go 為下面代碼
package controllerimport ("github.com/beego/beego/v2/server/web""strconv"
)type SessionController struct {web.Controller
}func (this *SessionController) GetUserInfo() {user := this.GetSession("user")if user == nil {this.SetSession("user", int(1))} else {this.SetSession("user", user.(int)+1)}res := "ok"if user != nil {res = res + strconv.Itoa(user.(int))}this.Ctx.WriteString(res)
}func (this *SessionController) PutCookie() {// 設置cookie 和 過期時間this.Ctx.SetCookie("name", "web cookie", 10)this.Ctx.WriteString("SetCookie ok")
}func (this *SessionController) ReadCookie() {name := this.Ctx.GetCookie("name")this.Ctx.WriteString(name)
}
在 main.go 中添加路由
package mainimport ("beego-demo/controller""beego-demo/filter""fmt""github.com/beego/beego/v2/core/config""github.com/beego/beego/v2/server/web""github.com/beego/beego/v2/server/web/context"_ "github.com/beego/beego/v2/server/web/session/redis""html/template""net/http"
)func main() {//通過config獲取自定義配置workername, _ := config.String("workername")fmt.Println(workername)//執行定時任務//go job.DemoTask()//注冊自動路由//web.AutoPrefix("api", &controller.UserController{})web.CtrlGet("/name", (*controller.UserController).Name)web.CtrlGet("/get/:id", (*controller.UserController).GetUserById)web.CtrlGet("/get/:id/:num", (*controller.UserController).GetUserByIdAndNum)//返回頁面web.CtrlGet("/page/index", (*controller.PageController).Index)web.CtrlGet("/page/f", (*controller.PageController).F)web.CtrlGet("/page/main", (*controller.PageController).Main)//web輸入參數web.CtrlGet("/pathparam/:name", (*controller.ParamController).PathParam)web.CtrlGet("/getparam", (*controller.ParamController).GetParam)web.CtrlPost("/postparam", (*controller.ParamController).PostParam)web.CtrlPost("/bindparam", (*controller.ParamController).BindParam)//上傳文件web.CtrlPost("/upload", (*controller.FileController).Upload)//下載文件web.CtrlGet("/download", (*controller.FileController).Download)//錯誤處理web.CtrlGet("/getUserName", (*controller.ErrorHandlerController).GetUserName)web.CtrlGet("/getUserAge", (*controller.ErrorHandlerController).GetUserAge)web.CtrlGet("/getUserAddr", (*controller.ErrorHandlerController).GetUserAddr)web.CtrlGet("/getUserGender", (*controller.ErrorHandlerController).GetUserGender)//注冊錯誤處理函數web.ErrorController(&controller.ErrorController{})//sessionweb.CtrlGet("/getUserInfo", (*controller.SessionController).GetUserInfo)//cookieweb.CtrlGet("/putCookie", (*controller.SessionController).PutCookie)web.CtrlGet("/readCookie", (*controller.SessionController).ReadCookie)//注冊函數式路由controller.RegisterFunctionalRoutes()//web命名空間controller.RegisterNamespaceRoutes()//過濾器filter.RegisterFilters()//開啟 Admin 管理后臺web.BConfig.Listen.EnableAdmin = trueweb.BConfig.Listen.AdminAddr = "localhost"web.BConfig.Listen.AdminPort = 8088//web.BConfig.WebConfig.ViewsPath = "pages"//開啟post 請求 bind綁定請求體web.BConfig.CopyRequestBody = true//查看已注冊路由tree := web.PrintTree()methods := tree["Data"].(web.M)for k, v := range methods {fmt.Printf("%s => %v\n", k, v)}//自定義模板函數web.AddFuncMap("bookName", bookName)//自定義401返回web.ErrorHandler("401", page401)//自定義404返回web.ErrorHandler("404", page404)web.ErrorHandler("dbError", dbError)web.BConfig.RecoverFunc = func(context *context.Context, config *web.Config) {if err := recover(); err != nil {context.WriteString(fmt.Sprintf("you panic, err: %v", err))}}web.Run()
}// 自定義模板函數添加書名號
func bookName(in string) (out string) {out = "《" + in + "》"return
}func page401(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("401.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/401.html")data := make(map[string]interface{})data["content"] = "沒有訪問權限"t.Execute(rw, data)
}func page404(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("404.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/404.html")data := make(map[string]interface{})data["content"] = "頁面沒找到"t.Execute(rw, data)
}func dbError(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("dberror.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/dberror.html")data := make(map[string]interface{})data["content"] = "我是自定義字符串錯誤類型處理函數"t.Execute(rw, data)
}
運行效果
瀏覽器請求:http://localhost:9090/putCookie
和?http://localhost:9090/readCookie
存儲 cookie 和 獲取 cookie
2.2、加密 Cookie 處理
Beego 提供了兩個方法用于輔助 Cookie 加密處理,它采用了sha256
來作為加密算法,下面Secret
則是加密的密鑰
修改 session.go 為下面代碼
package controllerimport ("github.com/beego/beego/v2/server/web""strconv"
)type SessionController struct {web.Controller
}func (this *SessionController) GetUserInfo() {user := this.GetSession("user")if user == nil {this.SetSession("user", int(1))} else {this.SetSession("user", user.(int)+1)}res := "ok"if user != nil {res = res + strconv.Itoa(user.(int))}this.Ctx.WriteString(res)
}func (this *SessionController) PutCookie() {// 設置cookie 和 過期時間this.Ctx.SetCookie("name", "web cookie", 10)this.Ctx.WriteString("SetCookie ok")
}func (this *SessionController) ReadCookie() {name := this.Ctx.GetCookie("name")this.Ctx.WriteString(name)
}func (this *SessionController) PutSecureCookie() {//my-secret 是加密的密鑰this.Ctx.SetSecureCookie("my-secret", "name", "web cookie")this.Ctx.WriteString("SetSecureCookie ok")
}func (this *SessionController) ReadSecureCookie() {name, _ := this.Ctx.GetSecureCookie("my-secret", "name")this.Ctx.WriteString(name)
}
在 main.go 中添加路由
package mainimport ("beego-demo/controller""beego-demo/filter""fmt""github.com/beego/beego/v2/core/config""github.com/beego/beego/v2/server/web""github.com/beego/beego/v2/server/web/context"_ "github.com/beego/beego/v2/server/web/session/redis""html/template""net/http"
)func main() {//通過config獲取自定義配置workername, _ := config.String("workername")fmt.Println(workername)//執行定時任務//go job.DemoTask()//注冊自動路由//web.AutoPrefix("api", &controller.UserController{})web.CtrlGet("/name", (*controller.UserController).Name)web.CtrlGet("/get/:id", (*controller.UserController).GetUserById)web.CtrlGet("/get/:id/:num", (*controller.UserController).GetUserByIdAndNum)//返回頁面web.CtrlGet("/page/index", (*controller.PageController).Index)web.CtrlGet("/page/f", (*controller.PageController).F)web.CtrlGet("/page/main", (*controller.PageController).Main)//web輸入參數web.CtrlGet("/pathparam/:name", (*controller.ParamController).PathParam)web.CtrlGet("/getparam", (*controller.ParamController).GetParam)web.CtrlPost("/postparam", (*controller.ParamController).PostParam)web.CtrlPost("/bindparam", (*controller.ParamController).BindParam)//上傳文件web.CtrlPost("/upload", (*controller.FileController).Upload)//下載文件web.CtrlGet("/download", (*controller.FileController).Download)//錯誤處理web.CtrlGet("/getUserName", (*controller.ErrorHandlerController).GetUserName)web.CtrlGet("/getUserAge", (*controller.ErrorHandlerController).GetUserAge)web.CtrlGet("/getUserAddr", (*controller.ErrorHandlerController).GetUserAddr)web.CtrlGet("/getUserGender", (*controller.ErrorHandlerController).GetUserGender)//注冊錯誤處理函數web.ErrorController(&controller.ErrorController{})//sessionweb.CtrlGet("/getUserInfo", (*controller.SessionController).GetUserInfo)//cookieweb.CtrlGet("/putCookie", (*controller.SessionController).PutCookie)web.CtrlGet("/readCookie", (*controller.SessionController).ReadCookie)web.CtrlGet("/putSecureCookie", (*controller.SessionController).PutSecureCookie)web.CtrlGet("/readSecureCookie", (*controller.SessionController).ReadSecureCookie)//注冊函數式路由controller.RegisterFunctionalRoutes()//web命名空間controller.RegisterNamespaceRoutes()//過濾器filter.RegisterFilters()//開啟 Admin 管理后臺web.BConfig.Listen.EnableAdmin = trueweb.BConfig.Listen.AdminAddr = "localhost"web.BConfig.Listen.AdminPort = 8088//web.BConfig.WebConfig.ViewsPath = "pages"//開啟post 請求 bind綁定請求體web.BConfig.CopyRequestBody = true//查看已注冊路由tree := web.PrintTree()methods := tree["Data"].(web.M)for k, v := range methods {fmt.Printf("%s => %v\n", k, v)}//自定義模板函數web.AddFuncMap("bookName", bookName)//自定義401返回web.ErrorHandler("401", page401)//自定義404返回web.ErrorHandler("404", page404)web.ErrorHandler("dbError", dbError)web.BConfig.RecoverFunc = func(context *context.Context, config *web.Config) {if err := recover(); err != nil {context.WriteString(fmt.Sprintf("you panic, err: %v", err))}}web.Run()
}// 自定義模板函數添加書名號
func bookName(in string) (out string) {out = "《" + in + "》"return
}func page401(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("401.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/401.html")data := make(map[string]interface{})data["content"] = "沒有訪問權限"t.Execute(rw, data)
}func page404(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("404.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/404.html")data := make(map[string]interface{})data["content"] = "頁面沒找到"t.Execute(rw, data)
}func dbError(rw http.ResponseWriter, r *http.Request) {t, _ := template.New("dberror.html").ParseFiles(web.BConfig.WebConfig.ViewsPath + "/dberror.html")data := make(map[string]interface{})data["content"] = "我是自定義字符串錯誤類型處理函數"t.Execute(rw, data)
}
運行效果
瀏覽器請求:http://localhost:9090/putCookie
和?http://localhost:9090/readCookie
存儲 cookie 和 獲取 cookie
更多API用法可以查看官方文檔
?
下一講:《Beego 使用教程 9:ORM 操作數據庫(上)》
至此完