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
参考
Last updated