Go Echo 学习笔记(七)会话控制


会话控制

在服务器中很多的场景中都要求区分当前访问的用户身份,但是 HTTP 协议本身是无状态的。因此,就得依靠其他的方式来获取对当前的会话进行控制。也就是 session 和 cookie

Cookie 是从 Web 服务器发送给浏览器并存储起来的一小段数据,当使用该浏览器再次访问该 Web 服务器的时候会携带该 Cookie,从而让 Web 服务器了解当前用户的身份信息。

在 Echo 中使用 http.Cookie 来实现会话控制的功能。

Attribute Optional
Name No
Value No
Path Yes
Domain Yes
Expires Yes
Secure Yes
HttpOnly Yes
type Cookie struct {
	Name  string  //cookie名字
	Value string  //cookie的值

	Path       string    // [可选字段] cookie路径
	Domain     string    // [可选字段] cookie作用域
	Expires    time.Time // [可选字段] cookie什么时候失效,需要设置一个具体的失效时间跟MaxAge字段二选一即可,

	// MaxAge=0 忽略MaxAge属性.
	// MaxAge<0 相当于删除cookie, 通常可以设置-1代表删除
	// MaxAge>0 多少秒后cookie失效
	MaxAge   int        // [可选字段] cookie有效期,单位是秒
	Secure   bool    // [可选字段] cookie secure属性
	HttpOnly bool    // [可选字段] cookie http only属性
}

在 Echo 中设置 Cookie 需要使用 Context#SetCookie() 方法:

cookie := new(http.Cookie)
cookie.Name = "username"
cookie.Value = "jon"
cookie.Expires = time.Now().Add(24 * time.Hour)
c.SetCookie(cookie) // 设置cookie

读取 Cookie 使用 Context#Cookie() 以及 Context#Cookies() 等方法:

// 按照 Name 属性读取指定cookie
cookie, err := c.Cookie("username")
if err != nil {
	return err
}

// 读取所有cookie
for _, cookie := range c.Cookies() {
	fmt.Println(cookie.Name)
	fmt.Println(cookie.Value)
}

Session

如果我们需要处理用户登录会话,就需要相关的 session 处理机制,Echo 框架的 session 处理是通过中间件实现的。

使用session的关键步骤:

  1. 导入依赖包
  2. 设置session中间件
  3. 读写session数据

导入依赖包

导入包之前先安装依赖包

go get github.com/gorilla/sessions
go get github.com/labstack/echo-contrib/session

导入包:

import (
  "github.com/gorilla/sessions"
  "github.com/labstack/echo-contrib/session"
)

设置session中间件

//初始化echo实例
e := echo.New()

//设置session数据保存目录
sessionPath := "./session_data"

//设置cookie加密秘钥, 可以随意设置
sessionKey := "Onxuh20a2ihhh2"

//设置session中间件
//这里使用的session中间件,session数据保存在指定的目录
e.Use(session.Middleware(sessions.NewFilesystemStore(sessionPath, []byte(sessionKey))))

读写session数据

下面以网站用户登录为例子介绍如何保存会话数据和读取会话数据。

首先登陆保存session:

e.POST("/login", func(c echo.Context) error {
    //获取登录请求参数
    username := c.FormValue("username")
    password := c.FormValue("password")
	
	//校验帐号密码是否正确	
    if username == "tizi365" && password == "123456" {
		//密码正确, 下面开始注册用户会话数据
		//以user_session作为会话名字,获取一个session对象
		sess, _ := session.Get("user_session", c)
		
		//设置会话参数
		sess.Options = &sessions.Options{
            Path:     "/",  //所有页面都可以访问会话数据
            MaxAge:   86400 * 7,   //会话有效期,单位秒
        }
        
        //记录会话数据, sess.Values 是map类型,可以记录多个会话数据
        sess.Values["id"] = username
        sess.Values["isLogin"] = true
        
        //保存用户会话数据
        sess.Save(c.Request(), c.Response())
        
		return c.String(200, "登录成功!")
	} else {
		return c.String(200, "密码不正确!")
	}
})

登陆成功后在其他地方获取session:

e.POST("/home", func(c echo.Context) error {
    //以user_session作为会话名字,获取一个session对象
    //注意这里的session名字,必须跟登录注册的会话名字一致
	sess, _ := session.Get("user_session", c)
	
	//通过sess.Values读取会话数据
	username := sess.Values["id"]
	isLogin  := sess.Values["isLogin"]
	
	//打印会话数据
	fmt.Println(username)
	fmt.Println(isLogin)
})