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 controller
import (
"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 main
import (
"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{})
//session
web.CtrlGet("/getUserInfo", (*controller.SessionController).GetUserInfo)
//注册函数式路由
controller.RegisterFunctionalRoutes()
//web命名空间
controller.RegisterNamespaceRoutes()
//过滤器
filter.RegisterFilters()
//开启 Admin 管理后台
web.BConfig.Listen.EnableAdmin = true
web.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 main
import (
"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{})
//session
web.CtrlGet("/getUserInfo", (*controller.SessionController).GetUserInfo)
//注册函数式路由
controller.RegisterFunctionalRoutes()
//web命名空间
controller.RegisterNamespaceRoutes()
//过滤器
filter.RegisterFilters()
//开启 Admin 管理后台
web.BConfig.Listen.EnableAdmin = true
web.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 controller
import (
"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 main
import (
"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{})
//session
web.CtrlGet("/getUserInfo", (*controller.SessionController).GetUserInfo)
//cookie
web.CtrlGet("/putCookie", (*controller.SessionController).PutCookie)
web.CtrlGet("/readCookie", (*controller.SessionController).ReadCookie)
//注册函数式路由
controller.RegisterFunctionalRoutes()
//web命名空间
controller.RegisterNamespaceRoutes()
//过滤器
filter.RegisterFilters()
//开启 Admin 管理后台
web.BConfig.Listen.EnableAdmin = true
web.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 controller
import (
"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 main
import (
"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{})
//session
web.CtrlGet("/getUserInfo", (*controller.SessionController).GetUserInfo)
//cookie
web.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 = true
web.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 操作数据库(上)》
至此完