cookie是客户端机制,把用户数据保存在客户端,而session是服务端机制,服务器使用一种类似于散列表的结构来保存信息,每一个网站访客都会被分配给一个唯一的标识符,即sessionID。
session和cookie
服务器使用session id来表示session,
- cookie
cookie是由浏览器维持的,存储在客户端的一小段文本信息,伴随着用户请求和页面在web服务器和浏览器之间传递。
cookie是有时间限制的,根据生命期不同分为两种:会话cookie和持久cookie;
会话cookie:只要关闭浏览器窗口,cookie就小时了,这种cookie一般保存在内存里。
持久cookie:如果设置了过期时间(setMaxAge(606024)),浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。这种cookie可以在不同的浏览器进程间共享。
- GO设置cookie
net/http包中的SetCookie来设置:
http.SetCookie(w ResponseWriter,cookie *Cookie)
w表示要写入的response,cookie是一个struct
type Cookie struct{
Name string
value string
path string
Domain string
Expires time.Time
RawExpires string
MaxAge int
Secure bool
HttpOnly bool
Raw string
Unparsed []string
}
例:
expiration := time.Now()
expiration = expiration.AddDate(1,0,0)
cookie := http.Cookie(Name:"username",Value:"astaxie",Expires:expiration)
http.SetCookie(w,&cookie)
- GO读取cookie
cookie,_ := r.Cookie("username")
fmt.Fprint(w,cookie)
for _,cookie := range r.Cookies(){
fmt.Fprint(w,cookie.Name)
}
seesion
session 在 Web 开发环境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器端之间保持状态的解决方案。有时候 Session 也用来指这种解决方案的存储结构。
但程序需要为某个客户端的请求创建一个 session 的时候,服务器首先检查这个客户端的请求里是否包含了一个 session 标识-称为 session id,如果已经包含一个 session id 则说明以前已经为此客户创建过 session,服务器就按照 session id 把这个 session 检索出来使用 (如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的 session 对象,但用户人为地在请求的 URL 后面附加上一个 JSESSION 的参数)。如果客户请求不包含 session id,则为此客户创建一个 session 并且同时生成一个与此 session 相关联的 session id,这个 session id 将在本次响应中返回给客户端保存。
- 小结
session通过cookie,在客户端保存session id,而将用户的其他回话消息保存在服务端session对象中,与此相对的,cookie将所有的信息都保存在客户端中。
GO如何使用session
- session创建过程
1、生成全局唯一标识符(seesion id)
2、开辟数据存储空间。(内存中或写入到文件、数据库里)
3、将session的全局唯一标识符发送给客户端。一般使用两种方式:cookie和url重写。
通过cookie:服务端通过设置set-cookie头就可以将session的标识符传送到客户端。
URL重写:返回用户页面里的所有的URL后面追加sessio标识符。如果客户端禁用了cookie,此种方案会是首选
- GO实现session管理
全局session管理器、保证session id的全局唯一性、为每个客户关联一个session、session的存储、session过期处理。
定义一个全局的session管理器:
type Manager struct {
cookieName string
lock sync.Mutex
provider Provider
maxLifeTime int64
}
func NewManager(provideName, cookieName string, maxLifeTime int64) (*Manager, error) {
provider, ok := provides[provideName]
if !ok {
return nil, fmt.Errorf("session: unknown provide %q (forgotten import?)", provideName)
}
return &Manager{provider: provider, cookieName: cookieName, maxLifeTime: maxLifeTime}, nil
}
Session接口:
设置值、读取值、删除值、获取session id
type Session interface {
Set(key, value interface{}) error // set session value
Get(key interface{}) interface{} // get session value
Delete(key interface{}) error // delete session value
SessionID() string // back current sessionID
}
预防session劫持
sessionID只允许cookie设置,而不是通过URL重置方式设置,同时设置cookie的httponly为true。在每个请求上加上token。
间隔生成新的SID