会话控制

HTTP 是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不
能区分中两次请求是否由一个客户端发出。这样的设计严重阻碍的 Web 程序的设计。
如:在我们进行网购时,买了一条裤子,又买了一个手机。由于 http 协议是无状态的,
如果不通过其他手段,服务器是不能知道用户到底买了什么。而 Cookie 就是解决方案
之一。

Cookie

简介

Cookie 实际上就是服务器保存在浏览器上的一段信息。浏览器有了 Cookie 之后,
每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以
根据该信息处理请求。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

Cookie 的运行原理

  1. 第一次向服务器发送请求时在服务器端创建 Cookie
  2. 将在服务器端创建的 Cookie 以响应头的方式发送给浏览器
  3. 以后再发送请求浏览器就会携带着该 Cookie
  4. 服务器得到 Cookie 之后根据 Cookie 的信息来区分不同的用户

创建 Cookie 并将它发送给浏览器

  1. 在服务器创建 Cookie 并将它发送给浏览器
    服务器端代码
func handler(w http.ResponseWriter, r *http.Request) {
cookie1 := http.Cookie{
Name: "user1",
Value: "admin",
HttpOnly: true,
}
cookie2 := http.Cookie{
Name: "user2",
Value: "superAdmin",
HttpOnly: true,
}
//将 Cookie 发送给浏览器,即添加第一个 Cookie
w.Header().Set("Set-Cookie", cookie1.String())
//再添加一个 Cookie
w.Header().Add("Set-Cookie", cookie2.String())
}

浏览器响应报文中的内容

HTTP/1.1 200 OK
Set-Cookie: user1=admin; HttpOnly
Set-Cookie: user2=superAdmin; HttpOnly
Date: Sun, 12 Aug 2018 07:24:49 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8
  1. 以后每次发送请求浏览器都会携带着 Cookie
GET /cookie HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62
Safari/537.36
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/
apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: user1=admin; user2=superAdmin
  1. 除了 Set 和 Add 方法之外,Go 还提供了一种更快捷的设置 Cookie 的方式,
    就是通过 net/http 库中的 SetCookie 方法

将 1)中的代码进行修改

func handler(w http.ResponseWriter, r *http.Request) {
cookie1 := http.Cookie{
Name: "user1",
Value: "admin",
HttpOnly: true,
}
cookie2 := http.Cookie{
Name: "user2",
Value: "superAdmin",
HttpOnly: true,
}
http.SetCookie(w, &cookie1)
http.SetCookie(w, &cookie2)
}

读取 Cookie

由于我们在发送请求时 Cookie 在请求头中,所以我们可以通过 Request 结构中的
Header 字段来获取 Cookie

  1. 处理器端代码
func handler(w http.ResponseWriter, r *http.Request) {
//获取请求头中的 Cookie
cookies := r.Header["Cookie"]
fmt.Fprintln(w, cookies)
}
  1. 浏览器中的结果

[user1=admin; user2=superAdmin]

设置 Cookie 的有效时间

Cookie 默认是会话级别的,当关闭浏览器之后 Cookie 将失效,我们可以通过 Cookie
结构的 MaxAge 字段设置 Cookie 的有效时间

  1. 处理器端代码
func handler(w http.ResponseWriter, r *http.Request) {
cookie := http.Cookie{
Name: "user",
Value: "persistAdmin",
HttpOnly: true,
MaxAge: 60,
}
//将 Cookie 发送给浏览器
w.Header().Set("Set-Cookie", cookie.String())
}
  1. 浏览器响应报文中的内容
HTTP/1.1 200 OK
Set-Cookie: user=persistAdmin; Max-Age=60; HttpOnly
Date: Sun, 12 Aug 2018 07:32:57 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

Cookie 的用途

  1. 广告推荐
  2. 免登录

Session

简介

使用 Cookie 有一个非常大的局限,就是如果 Cookie 很多,则无形的增加了客户
端与服务端的数据传输量。而且由于浏览器对 Cookie 数量的限制,注定我们不能再
Cookie 中保存过多的信息,于是 Session 出现。

Session 的作用就是在服务器端保存一些用户的数据,然后传递给用户一个特殊
的 Cookie,这个 Cookie 对应着这个服务器中的一个 Session,通过它就可以获取到保
存用户信息的 Session,进而就知道是那个用户再发送请求。

Session 的运行原理

  1. 第一次向服务器发送请求时创建 Session,给它设置一个全球唯一的 ID(可以通过
    UUID 生成)
  2. 创建一个 Cookie,将 Cookie 的 Value 设置为 Session 的 ID 值,并将 Cookie 发送
    给浏览器
  3. 以后再发送请求浏览器就会携带着该 Cookie
  4. 服务器获取 Cookie 并根据它的 Value 值找到服务器中对应的 Session,也就知道了
    请求是那个用户发的
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄