Go http服务器 Cookie和session

总所周知,http是无状态协议,即http的每次请求都是独立的,它不会受之前的请求影响,在这种情况下,对于服务器而言每次请求都全新的,所以服务器处理之前请求参数的数据都不会保留,会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。

http中的cookie是由服务器产生,发送给浏览器,当浏览器第二次访问统一网站时,携带cookie信息发送给服务器,服务器解析cookie中的信息,借此维护用户跟服务器会话中的状态。

总结一下Cookie的特点:

  1. 浏览器发送请求的时候,自动把携带该站点之前存储的Cookie信息。
  2. Cookie是一组键值对(key-val),可以设置其属性,例如keepalive、path等等
  3. 服务端可以设置Cookie数据。
  4. Cookie是针对单个域名的,不同域名之间的Cookie是独立的。
  5. Cookie数据可以配置过期时间,过期的Cookie数据会被系统清除。

go http中的Cookie

type Cookie struct {
        Name  string
        Value string

        Path       string    // optional
        Domain     string    // optional
        Expires    time.Time // optional
        RawExpires string    // for reading cookies only

        // MaxAge=0 means no \'Max-Age\' attribute specified.
        // MaxAge<0 means delete cookie now, equivalently \'Max-Age: 0\'
        // MaxAge>0 means Max-Age attribute present and given in seconds
        MaxAge   int
        Secure   bool
        HttpOnly bool
        SameSite SameSite
        Raw      string
        Unparsed []string // Raw text of unparsed attribute-value pairs
}

 go http中设置Cookie

func SetCookie(w ResponseWriter, cookie *Cookie) 

  w是请求的响应信息。

go http 操作Cookie:

package main

import (
        "net/http"
)

func SayOk(w http.ResponseWriter, r *http.Request) {
        cookie := &http.Cookie{
                Name:   "fly",
                Value:  "123456",
                MaxAge: 10,
        }
        cookie2 := &http.Cookie{
                Name:   "cc",
                Value:  "123456",
                Path:   "/aabb",
                MaxAge: 10,
        }
        http.SetCookie(w, cookie)
        http.SetCookie(w, cookie2)
        w.Write([]byte("你好,fly"))
}

func main() {
        http.HandleFunc("/", SayOk)
        http.ListenAndServe(":9999", nil)
}

  关于gin框架设置Cookie

package main

import (
        "github.com/gin-gonic/gin"
        "net/http"
)

func main() {
        e := gin.Default()
        e.GET("/", func(c *gin.Context) {
                c.SetCookie("username", "fly", 0, "", "", false, false)
                //c.Set("name","aaaabbbb")
                //c.JSON(http.StatusOK, "你好,世界")
                c.Redirect(http.StatusMovedPermanently, "/get")
        })
        e.GET("/get", func(c *gin.Context) {
                c.SetCookie("username", "fly", 0, "", "", false, false)
                c.JSON(http.StatusOK, "重定向:你好,世界")
        })
        e.Run(":9999")
}

  

Session

Cookie虽然在一定程度上解决了“保持状态”的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。

session 其实也是Cookie的数据,但是它具有唯一标识的特性即sessionid,浏览器每次请求的时候都携带cookie包括session ID,这样一组请求就关联起来了成为了一个session

go http并没有实现session的代码,可能session就是Cookie操作,所以就需要自己实现

注意:当浏览器关闭了一个session的时候,服务器并不知道,所以这是就需要浏览器发送通知让session老化