Session

简介

在上一篇文章中介绍了Cookie的内容。在HTTP Request中,可以在Header中携带Cookie给服务端;在HTTP Response中,可以在Header中携带Cookie返回给客户端。但是,Cookie的结构体一般是固定的,携带的信息有限。此时,我们可以在服务端保存客户端的相关信息,然后客户端请求时,只需要携带一个Id给服务端,服务端根据此Id查询客户端相关的信息,这就是Session的基本机制。

这里列出了Session与Cookie的几个区别:

  • Cookie是通过HTTP协议的请求头中的Cookie字段与响应头中的Set-Cookie字段进行传输的

  • Cookie的结构体是固定的,所携带的信息有限

  • Cookie由服务端生成,返回给客户端,客户端请求时,再携带给服务端。所以,Cookie是一种将状态信息存储在客户端的机制。

  • Session机制是将状态信息存储在服务端,然后通过Cookie把SessionId传回给客户端

  • Session的结构是不固定的,用户可以自已定义,存储的信息量比Cookie要多

  • Session的后端存储引擎也比较丰富,有memory、file、redis、mysql等。

示例

接下来,我们通过一个例子(go语言)来展示一下session的使用。解释一下这段代码的意思:

  • 在浏览器(客户端)上访问 x.x.x.x:8082/login?username=xxx 时,程序(服务端)会新建一个Session,记录登录的用户名,并把SessionId通过Cookie传回给浏览器

  • 在浏览器上访问x.x.x.x:8082/whoami时,浏览器会携带包含SessionId的Cookie给服务端,服务端根据SessionId查询到Session对象,得到用户名,返回给浏览器

  • 在浏览器上访问x.x.x.x:8082/logout时,浏览器会携带包含SessionId的Cookie给服务端,服务端会根据SeesionId删除对应的Session对象,并且告诉浏览器删除对应的Cookie

session.go

实验效果

  • 首先登录

首次访问/login?username=peng,服务端会返回一个Cookie给浏览器,包含了SessionId的内容

  • 携带上述的Cookie访问

接着,访问页面 /whoami,此时浏览器会携带Cookie给服务端,服务端根据Cookie中的SessionId查到出对应的Session,然后返回用户名给浏览器

  • 登出系统

访问/logout,浏览器把Cookie携带给服务端后,服务端会删除该SessionId的Session对象,并且告知浏览器出删除这个Cookie

  • 再次访问 /whoami

登出系统后,再次访问/whoami,由于浏览器没有携带SessionId相关的Cookie,所以服务端会报不知道客户端是谁

代码详细解析

  • sess, _ := globalSessions.SessionStart(w, r)

该语句的意思是从HTTP的请求头中读取承载SessionId的Cookie,然后在服务端查找出对应的Session对象,并且将该Cookie继续保存在HTTP的响应头中(http.RespondWriter);如果请求头中并没有相应的Cookie,则新建一个Session对象,并且把SessionId保存在Cookie中然后放到HTTP的响应头中。

  • sess.Set("username", queryUsername)

globalSessions.SessionStart(w, r)返回的Session对象的结构体与具体的后端存储有关,在上面的代码中我们使用的memory存储引擎。详细的类的定义见下面的内容

代码中各种结构体及函数的源码

  • func NewManager(...)

  • Manager struct

  • Store interface

  • MemSessionStore struct

参考

[1] https://beego.me/docs/module/session.mdarrow-up-right

Last updated